0

MSpec (James Broome による AutoMocking を使用) と RhinoMocks を使用して、BDD/TDD を使い始めたばかりです。以下は、私の実践プロジェクトからの抜粋です。

namespace Tests.VideoStore.Controllers
{
    public abstract class context_for_movie_controller :
    Specification<MovieController>
    {
        private static IList<Movie> movies;
        protected static IMovieRepository _movieRepository;
        protected static ActionResult _result;
        protected static string title;
        protected static string director;

        Establish context = () =>
        {
            _movieRepository = DependencyOf<IMovieRepository>();
        };
    }

    [Subject(typeof(MovieController))]
    public class when_searching_for_movies_with_director :
    context_for_movie_controller
    {
        Establish context = () =>
        {
            title = null;
            director = "James Cameron";

            var movie4 = new Movie {
                Title = "Terminator", Director = "James Cameron"};
            var movie6 = new Movie {
                Title = "Avatar", Director = "James Cameron"};

            movies = new List<Movie> {movie4, movie6};

            // Repository returns all movies.
            _movieRepository.Stub(x => x.FindMovies(title, director))
            .Return(movies);
        };

        Because of = () => _result = subject.Find(title, director);

        It should_fetch_movies_from_the_repository = () =>
            _movieRepository.AssertWasCalled(x =>
                x.FindMovies(title, director));

        It should_return_a_list_of_movies_matching_the_director = () =>
            _result.ShouldBeAView().And()
            .ShouldHaveModelOfType<IEnumerable<Movie>>)
            .And().ShouldContainOnly(movies);
    }

ご覧のとおり、MovieRepository クラスの FindMovies() メソッドをスタブ化しました。次に、MoviesController.Find() アクションを呼び出しています。私の質問は、スタブ化されたメソッド (FindMovies) がコントローラーによって呼び出されたかどうかを確認するアサートが必要ですか? それとも、結果がどこから取得されたかではなく、返された結果だけを気にする必要がありますか? さらに、「should_fetch_movies_from_the_repository」と書かれた仕様はエンジニアリング タスクのように見えますが、クライアントが理解できるものではありません。BDD でその場所があるのでしょうか?

4

1 に答える 1

1

アサーションについて従うべき一般的な規則は、入力相互作用ではなく、出力相互作用に対してアサートすることです。

FindMovies スタブは、それを呼び出したクラスに「映画」コレクションを返します。次に、「監督に一致する映画のリストを返す必要がある」というアサーションを介して、クラスが正しいリストを受け取ったことを確認します。FindMovies メソッドが呼び出されない場合、このアサーションは失敗します。

したがって、FindMovies メソッドに対して呼び出しをアサートする必要はありません。

これに対抗するために、純粋に出力されるモックまたはスタブがある場合、つまり、IView インターフェイスが Presenter クラスによって呼び出されているとしましょう。呼び出されている IView に対してアサートする必要があります。たとえば、次のコード:


public class MyPresenter
{
  ... other code here

  public DoSomething()
  {
    IList data = GetSomeData();
    myView.DisplayData(data);

  }
}

この場合、view.DisplayData メソッドが呼び出されたことをアサートする必要があります。これは、別のテストでアサートできるものをこの呼び出しから取得していないためです。

「リポジトリからのフェッチ」については、もちろん顧客はそれを気にかけています。彼らは、システムが映画をストレージに保存し、ストレージからロードすることを望んでいます。ただし ... FindMovies 呼び出しは、テスト対象のクラスへの入力であるため、この資産やテストはまったく必要ありません。FindMovies メソッドが呼び出されない場合、他のテストは失敗し、問題があることが通知されます。

于 2010-02-25T14:48:21.437 に答える