我剛剛開始使用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);
}
正如你所看到的,我掐滅了FindMovies上MovieRepository類()方法。然後我打電話給MoviesController.Find()動作。我的問題是,如果有一個斷言來檢查控制器是否調用了存根方法(FindMovies)?或者,我應該只關心返回的結果,而不關心它從何處被帶走?此外,規範中的「should_fetch_movies_from_the_repository」看起來很像工程任務,而不是客戶可能理解的東西 - 是否在BDD中佔有一席之地?
沒錯,現在我發現如果我在控制器操作中沒有使用FindMovies,測試會失敗。但是,如果我通過不同的方式創建相同的列表而不是調用FindMovies,測試會通過。我想我不應該關心數據來自哪裏,只要它是有效的,對吧? – 2010-02-26 10:21:22
你做,你不在乎。您關心的是數據是從外部存儲機制加載的 - 但您並不在乎它是如何從該存儲機制加載的。真正的好處是你不會創建脆弱的測試,當你改變你的API或實現時開始失敗。如果您決定使用一種名爲「FindMoviesInCache」的緩存機制將您的調用替換爲FindMovies,例如,只要存根的FindMoviesInCache返回正確的數據,您的測試仍會通過。 – 2010-02-26 12:29:32