Reputation: 23576
I have a Layout
that has a vent.on
call in it that gets setup on model initiation.
initialize: () ->
App.vent.on("deciseconds:updated", this.updateDVR)
updateDVR: () ->
console.log 'this updateDVR is called'
I want to make sure this.updateDVR
is hooked up correctly in my app. In my tests I have this:
beforeEach ->
this.showDvr = new Arc.DvrApp.Show.DvrView()
spyOn(this.showDvr, 'updateDVR')
it "calls updateDvr when new data comes in", ->
Arc.vent.trigger("deciseconds:updated")
expect(this.showDvr.updateDVR).toHaveBeenCalled()
This spec is failing, but when I check my log I am seeing this updateDVR is called
, the line I was logging in the updateDVR
function. So I know the function is being called.
It I directly call updateDVR
, the spec passes:
it "calls updateDvr when new data comes in", ->
this.showDVR.updateDVR()
expect(this.showDvr.updateDVR).toHaveBeenCalled()
I thought the vent
might be treated as an asynchronous function, so I tried waiting a few seconds before the expect
clause to see if that would work, but it didn't:
it "calls updateDvr when new data comes in", ->
Arc.vent.trigger("deciseconds:updated")
setTimeout(myCheck, 3000)
myCheck = () ->
expect(this.showDvr.updateDVR).toHaveBeenCalled()
Upvotes: 1
Views: 1913
Reputation: 626
The call to App.vent.on
in your initialize
function passes a reference to the view instance's this.updateDVR
function -- and that happens right before you spyOn(this.showDvr, ...)
in the test's beforeEach
. So when you trigger the event, the trigger calls that retained reference to the actual updateDVR
function, not the spy.
You should be able to fix it by passing a callback function to the App.vent.on
call, like so (sorry for the javascript, I'm not a coffeescripter!):
initialize: function () {
var that = this;
// hold onto the callback so we can unregister it in App.vent.off, too
this.onUpdateCb = function() { that.updateDVR() };
App.vent.on("deciseconds:updated", this.onUpdateCb );
// if this is a view, stop listening for App.vent when the view closes
this.listenTo(this, 'close', function() { App.vent.off("deciseconds:updated", this.onUpdateCb ) } );
}
That will make the event handler look up the symbol named "updateDVR" at the time the event is triggered, & it will call your spy as your test expects.
Edit: Updated to retain this.onUpdateCb so we can unregister the listener on close.
Upvotes: 2