【问题标题】:Backbone.js and Jasmine Spys Not Getting CalledBackbone.js 和 Jasmine Spys 没有被调用
【发布时间】:2011-11-10 19:59:47
【问题描述】:

我试图测试当一个元素被点击时,一个函数被调用。看起来很简单,但我一定错过了一些愚蠢的东西,因为我似乎无法让这个简单的例子工作。

这是我的观点

(function($) {
    window.LaserMonitor = {
        Views: {}
    };

    window.LaserMonitor.Views.WorkstationSummary = Backbone.View.extend({
        tagName: 'li',
        className: 'StationItem',

        initialize: function() {
            _.bindAll(this, 'showDetails');
            this.template = _.template($("#WorkstationSummary").html());
        },

        events: {
            'click h3' : 'showDetails'
        },

        showDetails: function() {
        },

        render: function() {
            var renderedTmpl = this.template(this.model.toJSON());

            $(this.el).append(renderedTmpl);

            return this;
        }
    });
})(jQuery);

这是我的茉莉花测试:

describe('WorkstationSummary Item', function() {
    beforeEach(function() {
        _.templateSettings = {
          interpolate: /\{\{(.+?)\}\}/g,
          evaluate: /\{\{(.+?)\}\}/g
        };      

        loadFixtures('LaserMonitorFixture.html');

        this.model = new Backbone.Model({
            id: 1,
            name: 'D8',
            assigned: 1900,
            inProgress: 4,
            completed: 5
        });

        this.view = new window.LaserMonitor.Views.WorkstationSummary({model: this.model});
    });

    describe('Events', function() {
        beforeEach(function() {
            this.view.render();
        });

        it('should trigger click event', function() {
            this.header = this.view.$('h3');

            spyOn(this.view, 'showDetails');

            this.header.click();

            expect(this.view.showDetails).toHaveBeenCalled();
        });
    });
});

本次运行的结果是:

错误:showDetails 上的预期间谍已被调用。 在新的(http://localhost:57708/JobMgr2/test-js/lib/jasmine-1.0.2/jasmine.js:102:32) 在 [object Object].toHaveBeenCalled (http://localhost:57708/JobMgr2/test-js/lib/jasmine-1.0.2/jasmine.js:1171:29) 在 [对象对象]。 (http://localhost:57708/JobMgr2/test-js/spec/LaserMonitorSpec.js:33:34) 在 [object Object].execute (http://localhost:57708/JobMgr2/test-js/lib/jasmine-1.0.2/jasmine.js:1001:15) 在 [object Object].next_ (http://localhost:57708/JobMgr2/test-js/lib/jasmine-1.0.2/jasmine.js:1790:31) 在http://localhost:57708/JobMgr2/test-js/lib/jasmine-1.0.2/jasmine.js:1780:18

编辑:为完整性添加夹具模板:

<script type="text/template" id="WorkstationSummary">
    <h3>{{ name }} ({{ assigned }}/{{ inProgress }}/{{ completed }})</h3>
    <ul>
    </ul>
</script>

【问题讨论】:

  • 没有茉莉花可以用吗?你试过“点击”它看看会发生什么吗?
  • 是的。我在那里放了一个console.log,它被调用了。这似乎很奇怪,因为我认为 spy 替换了该函数,除非您指定“andCallThrough”,否则不应调用它
  • 我认为这是stackoverflow.com/questions/6471457/…的骗子

标签: backbone.js jasmine


【解决方案1】:

如果你为方法创建了一个间谍,在运行测试时,而不是调用实际的方法,间谍会被调用。 spy 是该方法的包装器。但是这里的问题是您在创建间谍之前创建了视图。所以实际的方法被调用而不是间谍。您要做的是在创建视图对象之前创建间谍。我使用sinon.js 来监视这些方法。而且您必须使用视图的原型来监视该视图的方法:

var workStationSpy = sinon.spy(window.LaserMonitor.Views.WorkstationSummary.prototype, "showDetails");
this.view = new window.LaserMonitor.Views.WorkstationSummary({model: this.model});
this.view.render();
expect(workStationSpy).toHaveBeenCalled();
workStationSpy.restore();

【讨论】:

    【解决方案2】:

    我会将其更改为以下内容并尝试:

    it('should trigger click event', function() {
        var viewToTest = this.view;
        this.header = viewToTest.$('h3');
        spyOn(viewToTest, 'showDetails');
        this.header.click();
        expect(viewToTest.showDetails).toHaveBeenCalled(); 
    });
    

    我担心调用“this.view”可能会导致范围界定问题。这是一个疯狂的猜测,我没有测试过,但我认为值得一试。祝你好运!

    【讨论】:

    • 我认为您需要在 spyOn() 调用后调用 viewToTest.delegateEvents() 以刷新视图事件。
    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2012-08-04
    • 2012-08-26
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2016-09-09
    相关资源
    最近更新 更多