FluentAssertions应该包含失败但不应该失败

时间:2013-09-21 06:14:46

标签: .net collections enums contains fluent-assertions

我在使用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()。等于(“成功”)。

发生了什么事?

1 个答案:

答案 0 :(得分:1)

由于你的Roll()方法返回随机数,你的测试已经非常脆弱了。这可能只是随机性的结果。将表达式树传递给采用IEnumerable的方法是一种不好的做法,也是许多错误的根源。总是首先调用ToList()或ToArray()(虽然前者有点快)。