Monday, June 3, 2024
49
rated 0 times [  55] [ 6]  / answers: 1 / hits: 24329  / 11 Years ago, mon, august 19, 2013, 12:00:00

There is custom event fired in the FooView ..



// views/foo_view.js

this.trigger(something:happened);


The associated FooController binds a handler to take care of the event ...



// controller/foo_controller.js

initialize: function() {
this.fooView = new FooView();
this.fooView.bind(something:happened, this.onSomethingHappened, this);
}

onSomethingHappened: function(event) {
// Do something else.
}


To test the event handling I would write the following test for Jasmine:



it(should do something else when something happens, function() {
var fooController = new FooController();
spyOn(fooController, onSomethingHappened);
fooController.fooView.trigger(something:happened);
expect(fooController.onSomethingHappened).toHaveBeenCalled();
});


Though, the test fails ..



FooView should do something else when something happens.
Expected spy onSomethingHappened to have been called.
Error: Expected spy onSomethingHappened to have been called.
at new jasmine.ExpectationResult (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:114:32)
at null.toHaveBeenCalled (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1235:29)
at null.<anonymous> (http://localhost:8888/assets/foo_spec.js?body=true:225:47)
at jasmine.Block.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1064:17)
at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2096:31)
at jasmine.Queue.start (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2049:8)
at jasmine.Spec.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2376:14)
at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2096:31)
at onComplete (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2092:18)
at jasmine.Spec.finish (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2350:5)


Does the test fail because the event takes longer than the expectation to excute?


More From » asynchronous

 Answers
26

The problem is that you spy on a function after the function was bound to the event. When jasmine create a spy it will replace the function you spy on with another function.



So what happens here, is that the original function is bound to the event



this.fooView.bind(something:happened, this.onSomethingHappened, this);


After that, the original function is replaced by the spy, but that will not have any effect on the function you pass to the bind function.



The solution for that is to spy FooController.prototype.onSomethingHappened before you create a new instance:



it(should do something else when something happens, function() {
var onSomethingHappenedSpy = spyOn(FooController.prototype, onSomethingHappened);
var fooController = new FooController();
fooController.fooView.trigger(something:happened);
expect(onSomethingHappenedSpy).toHaveBeenCalled();
});

[#76272] Sunday, August 18, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
erinh

Total Points: 38
Total Questions: 100
Total Answers: 110

Location: Macau
Member since Mon, Nov 16, 2020
4 Years ago
;