我在使用Jasmine和Sinon的现有Backbone应用程序的测试套件上工作,我正在测试我的路由器在某个路由上执行正确的操作。这是实际的路线功能:
favourites: function()
{
//Dont re-initialize the favourites view as there is no need.
//Instead, just render the favourite movies
if ( ! this.favMoviesView)
{
this.favMoviesView = new cinephile.Views.FavouriteMoviesView({
collection: cinephile.favouriteMovies
});
}
else
{
this.favMoviesView.renderFavourites();
}
$('#content').html(this.favMoviesView.el);
},
在我的测试套件中,我想声明当导航到收藏夹路线this.favMoviesView
时会创建一次然后,如果它存在则不会重新初始化,而只是调用this.favMoviesView.renderFavourites()
,这是迭代视图集合的方法。
这是我的测试规范:
describe('cinephile.Routers.CinephileRouter', function () {
beforeEach(function () {
this.router = new cinephile.Routers.CinephileRouter();
this.routeSpy = sinon.spy();
try
{
Backbone.history.start({ silent : true });
}
catch(e) {}
this.router.navigate('elsewhere');
this.favouritesViewStub = sinon.stub(cinephile.Views, 'FavouriteMoviesView')
.returns(new Backbone.View());
});
afterEach(function () {
this.favouritesViewStub.restore();
});
describe('Favourites Route', function() {
it('should load the favourites on /favourites', function () {
this.router.bind('route:favourites', this.routeSpy);
this.router.navigate('favourites', true);
expect(this.routeSpy.calledOnce).toBeTruthy();
expect(this.routeSpy.calledWith()).toBeTruthy();
});
it('creates a favourites view if one doesn\'t exist', function () {
this.router.favourites();
expect(this.favouritesViewStub.calledOnce).toBeTruthy();
});
it('Reuses the favourites view if one does exist and reset it\'s collection', function () {
this.router.favourites();
this.router.favourites();
expect(this.favouritesViewStub.calledOnce).toBeTruthy();
expect(this.favouritesViewStub.renderFavourites).toHaveBeenCalledTwice();
});
});
});
我的前两个测试通过,我相信它们能正确描述路由器中的favourites
方法。第三个测试就是那个给我带来问题的测试。据我了解,因为我正在测试我的路由器而不是FavouriteMoviesView
我应该删除视图以保持测试隔离。如果这是正确的假设,我的问题就是存根将不会有renderFavourites
方法,因为它是一个存根Backbone.View()
。
我如何解决这个特殊问题,如果你如此倾向,我相信我会遗漏一些概念,所以请随意解释一下我不理解的问题。
干杯。
答案 0 :(得分:1)
你的问题是你想在mock函数中模拟一些东西。我建议的是,而不是这个......
this.favouritesViewStub = sinon.stub(cinephile.Views, 'FavouriteMoviesView').returns(new Backbone.View());
......有这个:
var StubView = Backbone.View.extend({
renderFavourites: sinon.stub()
});
this.favouritesViewStub = sinon.stub(cinephile.Views, 'FavouriteMoviesView').returns(new StubView());
现在你的View"构造函数"将返回StubView
,其中包含您调用的方法。所以这个带有stubbed out方法的Backbone View将放在router.favMoviesView
-property中。 favouritesViewStub
属性仍然只包含"构造函数" -function,因此您无法从那里访问此存根方法。这就是你必须从上一次测试中改变它的原因:
expect(this.favouritesViewStub.renderFavourites).toHaveBeenCalledTwice();
这样的事情:
expect(this.router.favMoviesView.renderFavourites).toHaveBeenCalledTwice();
通过这种方式,您将实际检查路由器的视图副本是否已将方法调用两次。
希望这对你有用,如果没有,请评论!我没有对此进行测试,因此可能存在一些问题,但我确信其背后的逻辑是有效的。