.net 当FluentAssertions不应';T

.net 当FluentAssertions不应';T,.net,collections,enums,contains,fluent-assertions,.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 (Symb

在使用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}时,它当然会失败。这是意料之中的。但是,有时会出现如下消息:

[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);
}
消息:ExpectedCollection{Success,Failure}包含成功

这到底是怎么回事?我做了一些挖掘,发现了很多关于Contains使用reference 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().Equals(“成功”)


发生了什么事?

因为Roll()方法返回的是随机数,所以测试已经相当脆弱。这可能只是随机性的结果。将表达式树传递到采用IEnumerable的方法中是一种不好的做法,也是许多错误的根源。始终先调用ToList()或ToArray()(尽管前者快一点)。

是否尝试在Select()后面追加ToArray()?因为现在您正在将一个表达式树传递到Should()。不,我没有,它看起来像我期望的那样工作。我真的不明白为什么我以前做的工作是有效的。我不认为随机值是问题所在。对于一个IEnumerable,你们通过一个表达式树,看起来确实击中了要害。你知道有什么好的文章或者阅读过关于为什么这是坏的,在封面下发生了什么,等等,这样我可以学到更多吗?谢谢你的帮助!这是最常见的问题之一