我对Jasmine和Marionette非常陌生,并寻求一些关于如何测试的帮助,甚至是考虑测试我的应用程序的正确方法。欢迎任何指示。
我有一个Marionette控制器,用于获取我的模型,实例化我的视图并渲染它们。我使用了本页底部的方法,以便在呈现视图之前获取模型:https://github.com/marionettejs/backbone.marionette/blob/master/upgradeGuide.md#marionetteasync-is-no-longer-supported。
我的控制器方法来获取模型并显示视图如下所示:
showCaseById: function(id){
App.models.Case = new caseModel({ id: id });
var promise = App.models.Case.fetch();
$.when(promise).then(_.bind(this.showContentView, this));
},
如您所见,它在获取模型后调用showContentView。那个方法在这里:
showContentView: function(model){
App.views.Body = new bodyView({
model: App.models.Case
});
App.views.Body.on('case:update', this.submitCase, this);
// this.layout is defined in the controller's initialize function
this.layout.content.show(App.views.Body);
},
测试此功能的正确方法是什么?我想在完成promise之后测试showContentView函数的调用。我应该如何分解这个规格?
感谢。
答案 0 :(得分:0)
首先,窥探你的showContentView方法并声明它已被调用:
it('showCaseById', function (done) {
var controller = new Controller();
spyOn(controller, 'showContentView');
controller.showCaseById('foo');
expect(controller.showContentView).toHaveBeenCalledWith(jasmine.any(caseModel));
});
其次,我建议你把对fetch()的调用存根,这样就不会打网络了,但是现在它开始变得有点毛茸茸了:
function caseModel() {
this.fetch = function () {
// return a promise here that resolves to a known value, e.g. 'blah'
};
}
现在,你可以有一个稍强的断言,但这有点不显眼,因为你正在摆弄你的依赖的内部:
expect(controller.showContentView).toHaveBeenCalledWith('blah');
通过覆盖caseModel,当你的控制器方法创建一个时,它会得到你的新版本而不是旧版本,你可以控制新版本的实现,只是为了这个测试。
有一些方法可以使这些代码更易于测试,但是看起来你刚刚开始测试我不会全部考虑。当你做更多的测试时,你肯定会为自己找到这些东西。
答案 1 :(得分:0)
首先,了解_.bind(fn, context)
实际上并不调用fn很重要。相反,它返回一个函数,在调用时将调用fn()
。 context
定义fn将在内部用作this
的对象。
没有必要,但您可以将showCaseById
写为:
showCaseById: function(id){
App.models.Case = new caseModel({ id: id });
var promise = App.models.Case.fetch();
var fn = _.bind(this.showContentView, this);
$.when(promise).then(fn);
},
正如我所说,这是不必要的,但现在你明白_.bind()
返回一个函数,而$.when(promise).then(...)
接受一个函数作为它的(第一个)参数。
要回答实际问题,您可以通过添加另一个App.models.Case.fetch()
语句并使用您自己选择的测试功能来确认已履行$.when(promise).then(...)
承诺。
showCaseById: function(id){
App.models.Case = new caseModel({ id: id });
var promise = App.models.Case.fetch();
$.when(promise).then(_.bind(this.showContentView, this));
// start: test
$.when(promise).then(function() {
console.log("caseModel " + id + " is ready");//or alert() if preferred
});
// fin: test
},
第二个$.when(promise).then(...)
不会干扰第一个console.log()
;相反,这两个将按顺序执行。 this.showContentView
satatement将提供可靠的确认,即this.showContentView
已被成功调用,并且初始渲染应该已经发生。
如果此时或之后没有呈现任何内容,则必须怀疑需要调试{{1}}。