问题
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. I've already know how to resolve the problem in the plunker from those answers. Still there is one unresolved question:
Why does the original function object is not being resolved?
I thought that the system works like this (assuming spyies decorate the function with additional logic)
When I have no spies when I call service.a
it's being resolved as:
A) service.a -> a()
and when I create a spy, it decorates the function
B) spy -> service.a => service.a*()
but the service.a
is basically a reference for original a()
so we should have a spy set for resolved function object in the end:
A + B => spy -> service.a -> a => a*()
回答1:
After you call spyOn(service, 'a')
, service.a
is no longer the a
you defined in the function -- it is a spy function. That spy function happens to call a
, but it is not a
; it has a different identity and is a different function.
However, setting the a
property of service
does not change the function a
you declared inside app.factory
. You've simply changed service
so that its a
property no longer refers to your original a
. By contrast, your b
function never changes its reference to the original a
. It gets a
straight from the local app.factory
scope in which a
and b
were originally declared. The fact that service
replaces its original a
with a spy does not affect b
's call to a()
, because it does not refer to service.a
.
来源:https://stackoverflow.com/questions/36222909/why-jasmine-spy-doesnt-resolve-the-function-object-by-reference