Reputation: 4277
I have the following simple service
app.factory('Shoes', function() {
function a() {return 12;}
function b() {return a();}
return {
a: a,
b: b
}
})
I want to test if the method a
is being called when I call method b
. My test looks like this:
describe('Testing a Shoes service', function() {
var service;
beforeEach(module('plunker'));
beforeEach(inject(function(Shoes) {
service = Shoes;
}))
it('.b should call .a', function() {
spyOn(service, 'a');
service.b();
expect(service.a).toHaveBeenCalled();
})
});
But the tests fail. Relevant plunker is here.
Question is how can I test this kind of interactions?
Upvotes: 0
Views: 1036
Reputation: 5736
What happens here is that you set on a spy on service.a
method, but the internal a
(which is called internally by b
) is still the same internal method (i.e not the spy), that's why your test fail.
If you really want to do that, the only way is to not call the internal a
but the method of your service:
app.factory('Shoes', function() {
return {
a: function a() {
return 12;
},
b: function b() {
return this.a();
}
};
});
Here is an update of your plunkr: https://plnkr.co/edit/6FZptdcX9qwyOE6kbgAX
EDIT:
Just some explanation: the service.a
method is just a pointer to the internal a
method. When you say spyOn(service, 'a')
, you are just overwriting the service.a
pointer to point to a completely different method (i.e a spy created by jasmine). The internal a
method is private and will be never updated, so if you call a()
in your internal b
method, you just call the original method a
not the spy pointed by service.a
.
Upvotes: 3
Reputation: 36
app.factory('Shoes', function() {
var self = {
a: function() {return 12;},
b: function() {return this.a();}
}
return {
a: self.a,
b: self.b
}
})
I believe that's because b is not calling the function you are spying on. With factory above test passes.
Upvotes: 0
Reputation: 730
I managed to fix this issue with the following code
app.factory('Shoes', function() {
var module = {
a:function(){
return 12;
},
b: function(){
return this.a();
}
}
return module;
});
It seems like your tested module can't just call a "function". It should call the method of the object returned;
Updated Plunker: https://plnkr.co/edit/DeDmdQq3rguO6uGHElW6?p=preview
Upvotes: 0