【问题标题】:Browser page keeps refreshing when testing Backbone views with Jasmine使用 Jasmine 测试 Backbone 视图时浏览器页面不断刷新
【发布时间】:2012-08-21 15:48:32
【问题描述】:

运行下面的 Jasmine 测试(1),测试成功但我面临主测试页面的递归加载。

这是我的测试 (1),这里是我运行测试的模块 (2):

有什么想法吗?我该如何解决这个问题?

附:
该问题仅与 Chrome 和 Safari 浏览器有关。
这是一个例子:jsfiddle.net/shioyama/EXvZY


(1)

describe('When Submit button handler fired', function () {
    beforeEach(function () {
        spyOn(MyView.prototype, 'submitForm');
        this.view = new MyView();
        this.view.render();
        this.view.$el.find('form').submit();
    });

    it('submitForm should be called', function () {
        expect(MyView.prototype.submitForm).toHaveBeenCalled();
    });
});

(2)

var MyView = Backbone.View.extend({
    events: {
        'submit form' : 'submitForm'
    },

    submitForm: function (event) {
        event.preventDefault();
        // some code
    }
});

【问题讨论】:

  • 我在这里为此创建了一个 jsfiddle:jsfiddle.net/shioyama/EXvZY/8。测试通过了,我没有看到任何递归加载,但也许我不知道要寻找什么。你能澄清一下你的意思吗?
  • 对不起,这是链接:jsfiddle.net/shioyama/EXvZY
  • @shioyama,感谢您创建了 jsfiddle。你明白我的意思吗?
  • 不,很遗憾,我看不到您在说什么。它是否出现在 jsfiddle 中?
  • @shioyama 你的jsfiddle.net/shioyama/EXvZY 就是一个很好的例子。无论如何,问题只涉及 Chrome 和 Safari。尝试在 Chrome 或 Safari 中运行 load jsfiddle.net/shioyama/EXvZY,您会看到问题。

标签: javascript backbone.js jasmine


【解决方案1】:

Backbone 使用委托事件,它们在创建视图时绑定。您的 view.el 在创建时不包含表单,而是在 render 方法中创建一个。这就是提交委托事件未绑定的原因,而是您在页面上提交表单的原因。该表单提交到相同的 URL,这会触发 Jasmine 套件再次运行,从而导致循环。

如果你稍微修改一下你的代码,你会发现这个版本可以工作,因为

元素在视图生成之前就已经存在了。

var MyView = Backbone.View.extend({
    events: {
        'submit form' : 'submitForm'
    },

    submitForm: function (event) {
        event.preventDefault();
        // some code
    }
});

//start test runner right after we're done defining our tests in this script
window.setTimeout( function(){
    jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
    jasmine.getEnv().execute();
}, 0 );

//TESTS GO HERE
describe('When Submit button handler fired', function () {
    beforeEach(function () {
        spyOn(MyView.prototype, 'submitForm').andCallThrough();
        this.view = new MyView({
            el: $('<div><form><input type="submit" value="Submit" /></form></div>')
        });
        this.view.$el.find('form').submit();
    });

    it('submitForm should be called', function () {
        expect(MyView.prototype.submitForm).toHaveBeenCalled();
    });
});​

【讨论】:

  • 感谢您的回答。你的解释很清楚。无论如何,如果我创建this.view 而不调用render,则在我执行测试this.view.$el.find('form').submit();this.view.$el.submit(); 时不会调用MyView.prototype.submitForm。有什么想法吗?
  • 这是使用您的建议 jsfiddle.net/EXvZY/19 的 jsfidlle,但它不起作用。如果我遗漏了什么,请纠正我!
  • 两件事:#1:委托事件使用选择器,因此它们不会绑定到根节点 - 我添加了一个 div 作为容器 & #2:您添加了一个间谍,但不要'不允许调用向下传播到被监视的元素,这意味着提交处理程序永远不会返回 false - 需要添加 .andCallThrough()。
  • 现在可以奖励赏金了吗? ;)
猜你喜欢
  • 2015-02-15
  • 2020-08-12
  • 2021-01-13
  • 2021-04-05
  • 2015-11-01
  • 2021-08-15
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多