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

Posted

技术标签:

【中文标题】如何使用 It.IsIn(someRange) 对多个字段的 POCO 属性组合进行迭代?【英文标题】:How iterate through combination of POCO properties using It.IsIn(someRange) for multiple fields? 【发布时间】:2016-04-10 22:11:57 【问题描述】:

我有一个 POCO 课程:

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

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

    Id = 1,FirstName = null,LastName = "Doe" Id = 1,FirstName = "",LastName = "Doe" Id = 1,FirstName = "John",LastName = "Doe" Id = 1,FirstName = null,LastName = "" 等

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

// 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 一次。

问题:如何查看所有可能值的组合?

【问题讨论】:

【参考方案1】:

您错误地使用了It.IsIn;它仅在matching arguments 时使用,即在Verify 调用中检查一个值是否在一组可能的值中,或者在Setup 调用中控制起订量如何响应。它不是设计用于以某种方式生成一组测试数据。这正是 NUnit 的 ValuesAttributeValueSourceAttribute 的用途。

关于你因为太多的组合而反对使用 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)。请注意,组合是默认设置。

但是,如果您只反对结果中的测试数量,那么请专注于您真正想要测试的内容并编写这些测试,而不是对所有可能的值进行猛烈抨击。

【讨论】:

非常感谢。这正是它!而且我不会“霰弹枪”,我只是在代码中有非常“if”'fy 逻辑)【参考方案2】:

由于 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);
    

【讨论】:

10 个有自己的范围的属性怎么样?

以上是关于如何使用 It.IsIn(someRange) 对多个字段的 POCO 属性组合进行迭代?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 scikit-learn 对文本对进行分类?

如何使用 Matlab 按字母顺序对属性值对进行排序

如何使用 JMeter 对 Websocket 进行负载测试?

如何对函数的输出使用索引? [复制]

如何使用优先队列对链表进行排序

如何对大数使用格式化