Tom*_*han 83 c# xunit xunit.net
我在我的测试套件中有一个类似这样的测试:
[Fact]
public void VerifySomeStuff()
{
var stuffCollection = GetSomeStuff();
Assert.Equal(1, stuffCollection.Count());
}
Run Code Online (Sandbox Code Playgroud)
这个测试按照我的预期工作,但是当我运行它时xUnit会输出一个警告:
警告xUnit2013:不要使用Assert.Equal()来检查集合大小.
但是,警告中没有建议替代方案,谷歌搜索会将我带到xUnit中的源代码,以便验证是否打印了此警告.
如果Assert.Equal()不是验证集合长度的正确方法,那是什么?
澄清一下:我意识到我可以通过例如提取变量或使用Assert.True(stuff.Count() == 1)替代来"欺骗"xUnit而不发出此警告.后者只是hacky,而前者感觉就像xUnit试图避免多次迭代一样IEnumerable<T>,那么这是错误的方法(因为我会分别得到编译器提示,如果这是一个问题),并且xUnit本身不应该多次评估输入(事实上,无论变量提取如何,它都可能获得相同的输入,因为C#函数调用的工作方式).
所以,我不仅仅想从我的输出中删除该警告.我的问题的答案也解释了为什么首先将警告包含在库中,以及为什么我应该使用的方法更好.
vcs*_*nes 89
Xunit为其大多数警告提供快速修复,因此您应该能够看到它认为"正确"的内容.
在您的情况下,它希望您使用,Assert.Single因为您只期望一个项目.如果你断言任意数字,比如412,那么它就不会给你一个关于使用的警告Count.它只会建议使用,Single如果您期望一个项目,或者Empty如果您不期望任何项目.
Tik*_*all 23
该规则仅在测试集合中的 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
Run Code Online (Sandbox Code Playgroud)
满足规则:
Assert.Empty(result); // for 0 items
Assert.Single(result); // for 1 item
Assert.NotEmpty(result); // for 1 or more items
Run Code Online (Sandbox Code Playgroud)
当使用 Assert.NotEmpty 时,我们最好用计数来精确
Assert.Equal(2, result.Length) // Does not violate rule xUnit2013
Run Code Online (Sandbox Code Playgroud)
https://xunit.net/xunit.analyzers/rules/xUnit2013
如果您有多个项目,则无法使用 Assert.Single。
期望似乎是你应该使用Assert.Collection:
var stuffCollection = GetSomeStuff();
Assert.Collection(stuffCollection,
item => Assert.True(true), // this lambda verifies the first item
item => Assert.True(true), // second item
);
Run Code Online (Sandbox Code Playgroud)
上面的断言验证了集合中恰好有两个项目。您可以提供更严格的 lambda(例如,item => Assert.Equals(7, item.property1)如果需要,可以为每个项目提供更严格的 lambda)。
就我个人而言,我不是粉丝;这似乎是一种非常冗长的方式来表达你想要的集合有多长。