Я только начинаю с BDD/TDD, используя MSpec (с AutoMocking Джеймсом Брумом) и RhinoMocks. Вот отрывок из моей практики проекта:Должен ли я проверить, был ли вызван метод stubbed?
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?
Правильно, теперь я вижу, что тест потерпит неудачу, если я не использовал FindMovies в действии контроллера. Однако, если я каким-то образом создал один и тот же список различными способами, чем вызов FindMovies, тест пройдет. Наверное, мне все равно, где данные поступают, если это действительно так, верно? –
вы делаете, и вы не заботитесь. вы заботитесь о том, чтобы данные были загружены из внешнего механизма хранения, но вам все равно, как он был загружен из этого механизма хранения. реальная выгода заключается в том, что вы не создаете хрупкие тесты, которые начинают сбой при изменении вашего API или реализации. если вы решили заменить свой вызов на FindMovies с помощью механизма кэширования, который, например, имел метод «FindMoviesInCache», ваш тест все равно будет проходить до тех пор, пока заглушенный FindMoviesInCache вернет правильные данные. –