我在我的测试套件中有一个类似这样的测试:
[Fact]
public void VerifySomeStuff()
{
var stuffCollection = GetSomeStuff();
Assert.Equal(1, stuffCollection.Count());
}
此测试按预期工作,但是当我运行它时xUnit会输出警告:
警告xUnit2013:不要使用Assert.Equal()来检查集合大小。
但是,警告中没有建议替代方案,谷歌搜索会将我带到xUnit中的源代码,以验证是否打印了此警告。
如果Assert.Equal()
不是验证集合长度的正确方法,那么它是什么?
澄清:我意识到我可以"欺骗" xUnit不通过例如发出此警告提取变量或使用Assert.True(stuff.Count() == 1)
代替。后者只是hacky,前者感觉就像xUnit是例如试图避免IEnumerable<T>
的多次迭代,那么这是错误的方法(因为我将分别得到关于它的编译器提示,如果它是一个问题),xUnit本身应该永远不会必须不止一次地评估输入(事实上,无论变量提取如何,它都可能获得相同的输入,因为C#函数调用的工作原理)。
所以,我不仅仅对从输出中删除警告感兴趣。我的问题的答案也解释了为什么首先将警告包含在库中,为什么我应该使用的任何方法都更好。
答案 0 :(得分:73)
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
答案 5 :(得分:-1)