在xUnit中验证集合大小的惯用方法是什么?

时间:2017-10-09 19:19:11

标签: c# xunit xunit.net

我在我的测试套件中有一个类似这样的测试:

[Fact]
public void VerifySomeStuff()
{
    var stuffCollection = GetSomeStuff();

    Assert.Equal(1, stuffCollection.Count());
}

此测试按预期工作,但是当我运行它时xUnit会输出警告:

  

警告xUnit2013:不要使用Assert.Equal()来检查集合大小。

但是,警告中没有建议替代方案,谷歌搜索会将我带到xUnit中的源代码,以验证是否打印了此警告。

如果Assert.Equal()不是验证集合长度的正确方法,那么它是什么?

澄清:我意识到我可以&#34;欺骗&#34; xUnit不通过例如发出此警告提取变量或使用Assert.True(stuff.Count() == 1)代替。后者只是hacky,前者感觉就像xUnit是例如试图避免IEnumerable<T>的多次迭代,那么这是错误的方法(因为我将分别得到关于它的编译器提示,如果它是一个问题),xUnit本身应该永远不会必须不止一次地评估输入(事实上,无论变量提取如何,它都可能获得相同的输入,因为C#函数调用的工作原理)。

所以,我不仅仅对从输出中删除警告感兴趣。我的问题的答案也解释了为什么首先将警告包含在库中,为什么我应该使用的任何方法都更好。

6 个答案:

答案 0 :(得分:73)

Xunit为其大多数警告提供快速修复,因此您应该能够看到它认为“正确”的内容。

xunit

在您的情况下,它希望您使用Assert.Single,因为您只需要一个项目。如果你断言任意数字,比如412,那么它就不会给你关于使用Count的警告。如果您期望一件商品,则只会建议使用Single;如果您不期待任何商品,则建议使用Empty

答案 1 :(得分:2)

我发现这给了我同样的错误:

Assert.Equal(2, vm.Errors.Count());

然后投射它可以阻止错误出现。

Assert.Equal(2, (int)vm.Errors.Count());

答案 2 :(得分:1)

对于列表中的单个元素,最好改为使用此元素: Assert.Single(resultList);

答案 3 :(得分:0)

如果有多个项目,则不能使用Assert.Single。

期望似乎应该使用Assert.Collection

var stuffCollection = GetSomeStuff();

Assert.Collection(stuffCollection, 
    item => true, // this lambda verifies the first item
    item => true, // second item
);

上面的断言验证集合中确实有两个项目。如果需要,您可以为每个项目提供更严格的lambda(例如item => item.property1 == 7)。

我个人不是粉丝;我个人不是粉丝。这似乎是一种非常冗长的方式来表达您希望集合多长时间。

答案 4 :(得分:0)

该规则仅适用于测试集合中的 0 或 1 个项目。

Assert.Equal(0, result.Length) // rule warning, use .Empty
Assert.Equal(1, result.Length) // rule warning, use .Single
Assert.Equal(2, result.Length) // ok

满足规则:

Assert.Empty(result); // for 0 items
Assert.Single(result); // for 1 item
Assert.NotEmpty(result); // for 2 or more items

当使用 Assert.NotEmpty 时,我们也可以精确计数

Assert.Equal(2, result.Length) // Does not violate rule xUnit2013

https://xunit.net/xunit.analyzers/rules/xUnit2013

答案 5 :(得分:-1)

当我在xUnit中使用Count属性时,我遇到了同样的问题。

enter image description here

之后,我在集合上使用Count()函数,它解决了我的问题。