1

有一个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");
4

0 回答 0