Должен ли я проверить, был ли вызван метод с заглушкой? - PullRequest
0 голосов
/ 25 февраля 2010

Я только начинаю с BDD / TDD, используя MSpec (с AutoMocking Джеймсом Брумом) и RhinoMocks. Вот выдержка из моего тренировочного проекта:

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);
    }

Как видите, я заглушил метод FindMovies () в классе MovieRepository. Затем я вызываю действие MoviesController.Find (). Мой вопрос заключается в том, должно ли быть утверждение, чтобы проверить, был ли вызван метод заглушки (FindMovies) контроллером? Или, может быть, я должен заботиться только о возвращенном результате, а не о том, откуда он был взят? Кроме того, спецификация, в которой написано «should_fetch_movies_from_the_repository», очень похожа на инженерную задачу, а не на то, что клиент может понять - есть ли она в BDD?

1 Ответ

1 голос
/ 25 февраля 2010

общее правило для утверждений состоит в том, что вы утверждаете против выходных взаимодействий, а не входных взаимодействий.

заглушка FindMovies возвращает коллекцию «movies» классу, который ее вызвал, и вы затем проверяете, что класс получил правильный список, через утверждение «он должен вернуть список фильмов, соответствующих директору». если метод FindMovies не вызван, то это утверждение не будет выполнено.

поэтому вам не нужно подтверждать вызовы метода FindMovies.

чтобы противостоять этому, если у вас есть макет или заглушка, которые являются чисто выходными данными - скажем, интерфейс IView, вызываемый классом Presenter, то вы хотите утверждать, что IView вызывается. например, этот код:


public class MyPresenter
{
  ... other code here

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

  }
}

вы хотели бы утверждать, что в этом случае вызывается метод view.DisplayData, потому что вы не извлекаете ничего из этого вызова, которое может быть подтверждено другим тестом.

что касается "выборки из хранилища" - конечно, ваши клиенты заботятся об этом. они хотят, чтобы система сохраняла фильмы в хранилище и загружала их из хранилища. однако ... вызов FindMovies является входом в тестируемый класс, поэтому совсем не обязательно иметь эту сборку или тест. если метод FindMovies не вызывается, то другой тест не пройден, и вы узнаете, что есть проблема.

...