使用Jasmine测试Backbone视图时,浏览器页面不断刷新

5
运行以下Jasmine测试,测试成功执行,但我面临着主测试页面的递归加载。

(2) 这是我的测试和我正在运行测试的模块:

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

P.S .:
该问题仅涉及Chrome和Safari浏览器。
这是一个例子:jsfiddle.net/shioyama/EXvZY

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:http://jsfiddle.net/shioyama/EXvZY/8/。测试通过,我没有看到任何递归加载,但也许我不知道该看什么。您能澄清一下您的意思吗? - Chris Salzberg
抱歉,这是链接:http://jsfiddle.net/shioyama/EXvZY/ - Chris Salzberg
@shioyama,感谢您创建了jsfiddle。你明白我的意思吗? - Lorraine Bernard
不幸的是,我不明白你在说什么。它在 jsfiddle 中显示吗? - Chris Salzberg
@shioyama,你的http://jsfiddle.net/shioyama/EXvZY/是一个很好的例子。不过,这个问题只涉及到Chrome和Safari浏览器。尝试在Chrome或Safari中加载http://jsfiddle.net/shioyama/EXvZY/,你会看到这个问题。 - Lorraine Bernard
哦,我明白了,我使用的是Firefox,这就解释了为什么我看不到它。 - Chris Salzberg
1个回答

3
Backbone使用委托事件,在视图创建时绑定。当您在渲染方法中创建表单时,view.el并不包含表单。因此,提交委托事件将无法绑定,导致您正在提交页面上的表单。该表单提交到相同的URL,触发Jasmine套件再次运行,导致循环。
如果您稍微修改代码,您会发现这个版本可以正常工作,因为<form>元素在视图生成之前就存在了。
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不会被调用。有什么想法吗? - Lorraine Bernard
这是使用您的建议创建的jsfidlle http://jsfiddle.net/EXvZY/19/,但它无法工作。如果我漏掉了什么,请纠正我! - Lorraine Bernard
两件事情:#1:委托事件使用选择器,所以它们不会绑定到根节点 - 我添加了一个div作为容器和#2:您添加了一个spy,但不允许调用向下传播到被观察的元素,这意味着提交处理程序永远不会返回false - 需要添加.andCallThrough()。 - Lauri Piispanen
现在可以请您颁发悬赏吗?;) - Lauri Piispanen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接