如何使用 It.IsIn(someRange) 对多个字段迭代 POCO 属性的组合?

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

我有一个 POCO class:

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

我想在 SomeEntity class 中使用不同的值测试其他一些 classes。问题是我需要测试许多属性的不同组合。例如:

  1. Id = 1,FirstName = null,LastName = "Doe"
  2. Id = 1, FirstName = "", LastName = "Doe"
  3. ID = 1,名字 = "John",姓氏 = "Doe"
  4. Id = 1,FirstName = null,LastName = ""
  5. 等等

所以在每个测试中我都想像这样创建测试对象:

// 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);

我不想使用 nunit TestCase,因为会有很多组合(巨大的矩阵)。

我尝试在调试中 运行 这个测试,它只使用列表中的第一个值调用 DoSomething 一次。

问题:我如何遍历所有可能值的组合?

由于每个 FirstName 和 LastName 都在一个列表中,看起来最简单的就是做 2 个循环

foreach (var fname in firstNamePossibleValues) {
    foreach (var lname in lastNamePossibleValues) {
        var testObject = new SomeEntity {
           Id = 1, // this must be always 1 for this test
           FirstName = fname, // each of this values must be accepted in test
           LastName = lname // each of this values must be accepted in test
        }

        var result = someOtherObject.DoSomething(testObject);
        Assert.AreEqual("some expectation", result);
    }
}

您使用 It.IsIn 不正确;它只能在 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 用于

时使用

关于你因为组合太多而反对使用NUnit,是因为你不想写所有的组合还是因为你不想那么多测试?如果是前者,则使用 NUnit 的属性和 CombinatorialAttribute 让 NUnit 完成创建所有可能测试的工作。像这样:

[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);
}

那个测试会运行9次(2个参数各3条数据,所以3*3)。请注意,组合是默认值。

但是,如果您只反对结果中的测试数量,那么请专注于您实际想要测试的内容并编写这些测试,而不是用每一个可能的值来解决它。