سؤال

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