有一个Marionette.js视图充当登录表单。以下代码示例显示了相关代码部分,包括我已经修复的错误:
MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {
User.LoginView = Marionette.ItemView.extend({
className: "reveal-modal",
template: "user/login",
ui: {
signInForm: "#signin-form"
},
events: {
"submit #signin-form": "onSignInFormSubmit"
},
onRender: function() {
var self = this;
var $el = this.$el;
// [...] Render schema
_.defer(function(){
$el.reveal({
closeOnBackgroundClick: false,
closed: function(){
self.close(); // <-- This is incorrect. Do not close the ItemView directly!
}
});
});
},
onSignInFormSubmit: function(event) {
event.preventDefault();
var errors = this.signInForm.validate();
var data = this.signInForm.getValue();
// [...] Notify that data has been submitted.
},
hideForm: function() {
this.$el.trigger("reveal:close");
}
});
});
我注意到我的实施中有一个重大错误。在Reveal的回调函数closed
中,我决定直接关闭ItemView ,这是错误的,您可以在Marionette.js 的文档中阅读:
View 实现了一个 close 方法,由区域管理器自动调用。
错误修正:应该在regionclose()
上调用。我修复了这个错误。
现在我问自己如何才能真正编写一个涵盖该问题的测试。我使用Jasmine进行测试。我注意到在我错误地关闭ItemView并尝试重新提交表单后,不再调用onSignInFormSubmit
事件处理程序。
这是测试的初稿,不幸的是,错误修复也失败了:
it("should call the submit handler for the sign-in form", function() {
spyOn(userController.loginView, "onSignInFormSubmit");
spyOn(userController.loginView.signInForm, "validate").andCallFake(function(params) {
return null;
});
userController.loginView.hideForm();
userController.loginView.ui.signInForm.trigger("submit");
expect(userController.loginView.onSignInFormSubmit).toHaveBeenCalled();
});
也许还可以测试事件处理程序是否已注册,例如:
expect(userController.loginView.events["submit #signin-form"]).toEqual("onSignInFormSubmit");