Question

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?

Was it helpful?

Solution

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top