Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How iterate through combination of POCO properties using It.IsIn(someRange) for multiple fields?

I have a POCO class:

public class SomeEntity {
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

I want to test some other classes using different values in SomeEntity class. The problem is that I need to test different combinations of many properties. For example:

  1. Id = 1, FirstName = null, LastName = "Doe"
  2. Id = 1, FirstName = "", LastName = "Doe"
  3. Id = 1, FirstName = "John", LastName = "Doe"
  4. Id = 1, FirstName = null, LastName = ""
  5. etc.

So in each test I want to create test object like this:

// test that someOtherObject always return the same result 
// for testObject with ID = 1 and accepts any values from range of 
// values for FirstName and LastName

var testObject = new SomeEntity {
  Id = 1, // this must be always 1 for this test
  FirstName = It.IsIn(someListOfPossibleValues), // each of this values must be accepted in test
  LastName = It.IsIn(someListOfPossibleValues) // each of this values must be accepted in test
}

var result = someOtherObject.DoSomething(testObject);

Assert.AreEqual("some expectation", result);

I don't want to use nunit TestCase as there will be many combinations (huge matrices).

I tried to run this test in debug and it makes call DoSomething only once with first values from list.

Question: how can I go through a combination of all possible values?

like image 239
Dzianis Yafimau Avatar asked Oct 19 '22 18:10

Dzianis Yafimau


1 Answers

You're using It.IsIn incorrectly; it's only meant to be used when matching arguments, i.e. in Verify calls to check that a value is in a set of possible values, or in Setup calls to control how the Moq responds. It is not designed to be used to somehow generate a set of test data. That's exactly what NUnit's ValuesAttribute and ValueSourceAttribute are for.

Regarding your objection to using NUnit because of too many combinations, is that because you don't want to write all the combinations or because you don't want that many tests? If it's the former, then use NUnit's attributes and the CombinatorialAttribute to make NUnit do the work of creating all the possible tests. Something like this:

[Test]
[Combinatorial]
public void YourTest(
    [Values(null, "", "John")] string firstName, 
    [Values(null, "", "Doe")] string lastName)
{
    var testObject = new SomeEntity {
        Id = 1, // this must be always 1 for this test
        FirstName = firstName,
        LastName = lastName
    };

    var result = someOtherObject.DoSomething(testObject);

    Assert.AreEqual("some expectation", result);
}

That test will be run 9 times (3 pieces of data for each of the 2 parameters, so 3*3). Note that combinatorial is the default.

But if you object to just the number of tests in your results, then focus on what you actually want to test and write those tests, rather than shotgunning it with every possible value.

like image 128
Patrick Quirk Avatar answered Oct 22 '22 01:10

Patrick Quirk