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 回ロールして、少なくとも両方の値を 1 回生成すると仮定することでした。しかし、数値を下げて (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} には、Success が含まれています。

ここで何が起こっているのですか?私はいくつかの掘り下げを行い、値が等しいのではなく参照が等しいを使用して、Contains に関する多くのことを見つけました。先に進みたいので、これを試しました:

[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 に答える