我有一个有角度的服务。在这个服务中,我有一个带有函数的对象,它引用了服务上的另一个函数。 (以下代码)
我想使用Jasmine(1.3)监视我的服务函数,以验证当调用对象的函数时,它实际上调用了真正的函数。
我的问题:在调用spyOn之后,仍然会调用真正的函数。
FooService.js
angular.module('foo').service("FooService", function() {
var self = this;
this.fooFunction = function() {
console.log("Foo function is being called");
}
this.bar = {
barFunction : self.fooFunction
}
});
FooService接口-spec.js
describe("Testing FooService", function() {
var service;
beforeEach(inject(function(_FooService_) {
service = _FooService_;
}));
describe("Test bar object", function() {
it("should call fooFunction when bar.barFunction is called", function() {
spyOn(service, "fooFunction");
service.bar.barFunction();
expect(service.fooFunction).toHaveBeenCalled();
});
});
});
我发现如果我将FooServce.js改为以下内容,这一切都有效:
FooService - 工作
angular.module('foo').service("FooService", function() {
var self = this;
this.fooFunction = function() {
console.log("Real function is being called");
}
this.bar = {
barFunction : function() {
return self.fooFunction();
}
}
});
我在第一个例子中没有理解JavaScript / Angular / Jasmine的哪个部分?
答案 0 :(得分:0)
spyOn
通过使用不同的值替换对象属性的值来进行操作。当您spyOn(service, "fooFunction");
执行
var realFunc = service.fooFunction;
service.fooFunction = function() {
doSpyStuff();
return realFunc.apply(this, arguments);
}
请注意,这不会修改值service.fooFunction
。它实际上修改了service
- 即service
的一个属性现在是一个完全不同的函数。此替换只会影响fooFunction
的{{1}}属性。如果您未访问service
的媒体资源,那么您肯定无法调用间谍功能。
因此,让我们将这些知识运用到您的案例中。在您的测试中,您正在访问service
的属性。虽然service.bar
和service.bar.barFunction
最初是相同的值,但service.fooFunction
已将其service
属性替换为间谍,而(非常重要的)fooFunction
尚未拥有由service.bar
变异的任何属性。当您致电spyOn
时,您直接调用真实函数,并且与service.bar.barFunction()
service
财产上的间谍无关。
相比之下,当您fooFunction
作为匿名函数执行时,您实际上 访问barFunction: function() { return self.fooFunction(); }
上的间谍属性值,因为此处service
恰好是self
,因此service
是self.fooFunction
,这是保存间谍重置价值的属性。