0

我在使用 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
}

我想做一些快速的理智检查,我实际上是在创建一个返回随机值的骰子,而不是总是相同的值。因此,我对 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} 包含成功。

这到底是怎么回事?我做了一些挖掘,发现很多关于包含使用引用等于而不是值等于的东西。想要继续前进,我尝试了这个:

[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().Equals("Success") 的项目。

这是怎么回事?

4

1 回答 1

1

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

于 2013-09-21T07:48:48.697 回答