Backbone - 使用Jasmine测试一个简单的模型会导致TypeError

时间:2011-12-17 07:18:45

标签: backbone.js jasmine

我试图学习使用Jasmine测试基于Backbone的应用程序的方法。为此,我从这里获取了一些示例代码:http://msdn.microsoft.com/en-us/scriptjunkie/hh377172

    Photo = new Backbone.Model.extend({
        defaults:{
            title: 'Another photo!',
            tags:  ['untagged'],
            location: 'home',
            src: 'placeholder.jpg'
        },
        initialize: function(){
            console.log('this model has been initialized');
            this.bind("change:title", function(){
                var title = this.get("title");
                console.log("My title has been changed to.." + title);
            });
        },

        setTitle: function(newTitle){
            this.set({ title: newTitle });
        }
    });

然后编写测试规范如下:

    describe("Photo Model", function() {
        it("verifies title", function() {
        var myPhoto = new Photo();
        myPhoto.set({ title: "On the beach" });   
        expect(myPhoto.get("title"))
            .toEqual("On the beach");
        });
    });

在运行它时,测试因TypeError

而失败
    TypeError: Object [object Object] has no method 'apply'
        at new <anonymous> (http://localhost:88/backbone/WebClient-Backbone2/js/backbone.js:1103:41)
        at [object Object].<anonymous> (http://localhost:88/backbone/WebClient-Backbone2/test/spec.js:28:16)
        at [object Object].execute (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:1001:15)
        at [object Object].next_ (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:1790:31)
        at [object Object].start (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:1743:8)
        at [object Object].execute (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:2070:14)
        at [object Object].next_ (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:1790:31)
        at [object Object].start (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:1743:8)
        at [object Object].execute (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:2215:14)
        at [object Object].next_ (http://localhost:88/backbone/WebClient-Backbone2/test/lib/jasmine/jasmine.js:1790:31)     

3 个答案:

答案 0 :(得分:8)

正如评论中所提到的,我发现,这是由于模型定义中的“新”。

所以,改变后,

    var Photo = new Backbone.Model.extend({

    var Photo = Backbone.Model.extend({

错误消失了。

答案 1 :(得分:2)

有一套很好的教程可以在这里使用Jasmine测试基于骨干的应用程序: http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html

答案 2 :(得分:1)

下面的代码片段可能是罪魁祸首。

this.bind("change:title", function(){
  var title = this.get("title");
  console.log("My title has been changed to.." + title);
});

在Javascript中,关键字的范围上下文基于它所处的功能。由于位于匿名函数内(this.bind(“更改”) :title“, function()),然后更改了其范围。

简单的解决方案是使用闭包将 this 设置为匿名函数之外的另一个变量,然后您可以在匿名函数中使用该变量。

显示代码示例可能更好地解释它。将初始化方法更新为以下内容。

    initialize: function(){
        console.log('this model has been initialized');
        var self = this;
        this.bind("change:title", function(){
            var title = self.get("title");
            console.log("My title has been changed to.." + title);
        });
    },

setTitle()方法也会遇到同样的问题。您需要在 initialize()方法中添加此行代码,以正确设置的上下文。

_.bindAll(this, "setTitle");