我在使用FluentAssertions编写的测试中遇到了一些奇怪的行为。我有以下课程:
public class Die
{
Random rand;
public Die()
{
rand = new Random();
}
public Symbol Roll()
{
var symbols = Enum.GetValues(typeof(Symbol));
return (Symbol)symbols.GetValue(rand.Next(symbols.Length));
}
}
public enum Symbol
{
Success,
Failure
}
我想做一些快速的理智检查,我实际上正在创建一个返回随机值的die,而不是总是相同的值。所以我对TDD的“快速和肮脏”是将它滚动100次并假设它至少产生两次值。但是,我注意到当我把数字降低(到10)时,我遇到了一些我没想到的失败。将它降为2看起来像这样:
[TestMethod]
public void Test_Die_Roll_Returns_Multiple_Values()
{
Die die = new Die();
Enumerable.Range(1, 2)
.Select((x) => die.Roll()).Should().Contain(Symbol.Success);
}
有时当我运行此测试时,它会通过。有时,它失败了,当然当集合是{Failure,Failure}时。这是预料之中的。但是,有时会失败并显示如下消息:
消息:ExpectedCollection {Success,Failure}包含成功。
这到底是怎么回事?我做了一些挖掘,发现很多关于Contains的东西使用引用equals而不是value equals。想要继续前进,我尝试了这个:
[TestMethod]
public void Test_Die_Roll_Returns_Multiple_Values()
{
Die die = new Die();
Enumerable.Range(1, 2)
.Select((x) => die.Roll()).Should().Contain(s => s.ToString().Equals("Success"));
}
有时只能获得通行证,有时会得到:
消息:集合{Success,Failure}应该有一个项目 匹配s.ToString()。等于(“成功”)。
发生了什么事?
答案 0 :(得分:1)
由于你的Roll()方法返回随机数,你的测试已经非常脆弱了。这可能只是随机性的结果。将表达式树传递给采用IEnumerable的方法是一种不好的做法,也是许多错误的根源。总是首先调用ToList()或ToArray()(虽然前者有点快)。