0

TDD 中に内部フィールドを設定するためにリフレクションを使用することは悪いことであると多くの場所で読みました。これはおそらく、テスト対象のクラスのインターフェイスをまだソートしていないことを意味するからです。ただし、完全にもっともらしいと思われるシナリオを提示したいと思います。リフレクション以外に、当面の問題に対する明確な解決策は考えられません。

対応するテストを含むクラスの例を次に示します。

public Class Movie
{
   public string MovieName{get; private set}

   public void AddExternalReview(IMovieReview review)
  {
      //Logic that needs Unit testing.
      if ( review.MovieName.Equals(MovieName) )
      {
         //Do stuff..
      }
  } 
}

単体テスト:

[Test]
public Class MovieTests
{
   public void CanAddExternalReview()
   {
      MovieReviewStub movieReviewStub = new MovieReviewStub(); 
      movieReviewStub.MovieName = "The Godfather";

      Movie m = new Movie();
      //Need to Set object m state(i.e set Property MovieName to "The Godfather")
      //Only way to do that seems to be relection.

      m.AddExternalReview(movieReviewStub);
      //Assert on some condition.
   }
}

クラスの「通常の」クライアントが設定できないプロパティを持つことはよくあることです。ただし、UnitTest クラスは、テストに必要な関連状態を設定できるように、そのようなプロパティ/フィールドにアクセスする必要がある場合があります。私が見る限り、反射が唯一の方法です。これは非常に一般的な要件であるに違いありませんが、Web 上のほとんどの記事や議論は、TDD でのリフレクションの使用に眉をひそめているようです。どんなアイデアや洞察も大歓迎です。

4

2 に答える 2

1

テストされているロジックに、満たされていない依存関係があるようです。テストには満たされていない前提条件があり、その前提条件が値を設定します。

リフレクションを使用せずに手動で値を設定するコードには、クリーンな方法はありません。では、なぜコードで論理的に起こらない何かをテストするのでしょうか?(コードがリフレクションを使用して値を設定している場合を除きます。その場合、クラスに抽象化の問題が確実にあります。)

クラスが何らかの理由でそのセッターを保護している場合は、その保護の範囲内で作業してください。そうしないと、あなたが言うように、インターフェースは適切に分類されません。その値を設定する論理プロセスが何であれ、テストの前提条件です。

于 2012-05-05T00:51:05.963 に答える
0

あなたの問題の説明で私を困惑させる文は、「クラスの「通常の」クライアントによって設定できないプロパティを持つことは非常に一般的です」です。これは、クラスに2つ(またはそれ以上)のタイプのクライアントがあるようです。その場合、さまざまなタイプのクライアントにさまざまなインターフェイスが表示されます。ただし、実装クラスは同じであり、プロパティのセッターを非表示にしないでください。テストの作成は簡単です。

結局のところ、設計の優先順位の問題に帰着すると思います。TDDを行うとき、私は通常、データの非表示とカプセル化よりもテスト容易性を優先します。逆の優先順位を付けると、例のように、テストが難しく直感的でない場合があります。

于 2012-05-05T20:21:05.593 に答える