I have the following view:

  ...
  var TreeView = Backbone.View.extend({
    el: '#org-tree',

    initialize: function() {
      eventBus.on("route:change", _.bind(this.triggerFilterEvent, this));
    },

    render: function() { ... },

    foo: function() { console.log("foo"); },

    triggerFilterEvent: function(name) {
      this.foo();
      ...
    }

  });
  ...

My Spec looks the following:

 describe('TreeView', function() {
    var treeView = new TreeView();

    it('calls triggerFilterEvent when receiving a route:change', function() {
      spyOn(treeView, 'triggerFilterEvent');
      spyOn(treeView, 'foo');
      treeView.delegateEvents();
      eventBus.trigger("route:change", "test");
      console.log('TriggerCOunt:' + treeView.triggerFilterEvent.callCount);
      console.log('FooCount: ' + treeView.foo.callCount);
      expect(treeView.triggerFilterEvent).toHaveBeenCalled();
    });
  });

I added treeView.delegateEvents() as suggested in the following solution: SpyOn a backbone view method using jasmine

However my test still fails with:

LOG: 'triggerFilterEvent with: test'
LOG: 'Event has been triggered: route:change'
LOG: 'TriggerCOunt:0'
LOG: 'FooCount: 1'
Error: Expected spy triggerFilterEvent to have been called.

The method foo is called once as expected though, how come?

有帮助吗?

解决方案

The issue is at the time you assign a spy on triggerFilterEvent, an event listener is already set to call the original function and not the spy (initialize is called when you initialize the view)

To get around that you can spy on the prototype, before you initialize the view :

spyOn(TreeView.prototype, 'triggerFilterEvent');
var treeView = new TreeView();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top