Reputation: 118
In angular, I am calling a method when an event listened for by $rootScope.$on
is fired.
$rootScope.$on('someEvent', some.method);
I am spying on the method in my jasmine tests, firing the event from my tests and then checking to see if the method was called.
spyOn(some, 'method');
$rootScope.$broadcast('someEvent');
expect(some.method).toHaveBeenCalled(); // fails
This test fails. Also, the method is actually called (verified through console logs).
Now, I can wrap the method in an anonymous function like so:
$rootScope.$on('someEvent', function () { some.method(); });
And the tests pass.
spyOn(some, 'method');
$rootScope.$broadcast('someEvent');
expect(some.method).toHaveBeenCalled(); // passes
In this case, the method itself is not actually called (as expected, because it is being spied on).
I have set up a suite of tests to fully illustrate in this Plunk: http://plnkr.co/edit/3S5J47OeCBsL0RASGe5P?p=preview
The method passed to $rootScope.$on
is called when the event fires regardless of whether it is wrapped in an anonymous function. However the spy only registers when wrapped in an anonymous function.
In jasmine, is it possible to successfully spy on an angular function passed by reference to $rootScope.$on
. If so, how? If not, why not?
Upvotes: 1
Views: 510
Reputation: 1676
spyOn() is a mutator. I forked your Plunk and added some some console logs.
Consider the call to register a spy:
spyOn(test, 'bar').andCallThrough();
This creates a new spy function that does the spy work and then calls the spied function. The spy is then stored on the object in place of the original function. In your "without anonymous wrapper" example you register the event to call the function that is value of test.bar
at the time the spy is registered:
$rootScope.$on('withoutFunctionWrapper', test.bar);
Whereas with the wrapper, the event will trigger whatever test.bar
is set to at the time of the event, which in your case is the spy:
$rootScope.$on('withFunctionWrapper', function() {
test.foo();
});
To illustrate:
So you could try calling spyOn()
first, if the function you're spying on can be made available before $rootScope.$on()
is called. Otherwise, you'll need the wrapper.
Upvotes: 2