我有以下简单的服务
app.factory('Shoes', function() {
function a() {return 12;}
function b() {return a();}
return {
a: a,
b: b
}
})
我想测试在调用方法a
时是否正在调用方法b
。我的测试看起来像这样:
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();
})
});
但测试失败了。相关的plunker是here。我已经知道如何从those answers解决问题。还有一个未解决的问题:
为什么原始功能对象没有被解析?
我认为系统的工作方式是这样的(假设spyies用额外的逻辑来装饰函数)
当我致电service.a
时我没有间谍时,它被解决为:
A) service.a -> a()
当我创建一个间谍时,它会修饰函数
B) spy -> service.a => service.a*()
但是service.a
基本上是原始a()
的引用,所以我们最终应该为已解析的函数对象设置一个间谍集:
A + B => spy -> service.a -> a => a*()
答案 0 :(得分:3)
致电spyOn(service, 'a')
后,service.a
不再是您在函数中定义的a
- 它是间谍功能。该间谍功能恰好调用a
,但不是a
;它具有不同的身份,是一种不同的功能。
但是,设置a
service
属性不会更改您在function a
内声明的app.factory
。您只是更改了service
,因此其a
属性不再引用您的原始a
。相比之下,您的b
函数永远不会更改其对原始a
的引用。它从最初声明a
和app.factory
的本地a
范围直接获得b
。 service
替换其原始a
与间谍的事实不会影响b
对a()
的调用,因为它不会引用service.a
}。