我有一个 Angular 服务。在这个服务中,我有一个带有函数的对象,它引用服务上的另一个函数。 (代码如下)
我想使用 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 的哪一部分?
最佳答案
spyOn
通过将对象属性的值替换为不同的值来进行操作。当你执行 spyOn(service, "fooFunction");
你正在做类似的事情
var realFunc = service.fooFunction;
service.fooFunction = function() {
doSpyStuff();
return realFunc.apply(this, arguments);
}
请注意,这不会修改值 service.fooFunction
。它实际上修改了 service
—— 也就是说,service
的属性之一现在是一个完全不同的函数。此替换只会影响 service
的 fooFunction
属性。如果您没有访问 service
的属性,那么您肯定不会调用 spy 功能。
所以让我们将这些知识应用到您的案例中。在您的测试中,您正在访问 service.bar
的属性。虽然 service.bar.barFunction
和 service.fooFunction
最初是相同的值,但 service
拥有其 fooFunction
属性被 spy 取代,而(非常重要的是)service.bar
的任何属性都没有被 spyOn
改变。当您调用 service.bar.barFunction()
时,您直接调用真正的函数,并且与 service
的 fooFunction< 上的 spy 没有任何连接
属性。
相比之下,当你执行 barFunction: function() { return self.fooFunction(); 时}
作为一个匿名函数,您实际上正在访问 service
上的 spy 属性值,因为这里 self
恰好是 service
,因此 self.fooFunction
是 service.fooFunction
,它是保存 spy 替换值的属性。
关于javascript - Jasmine:在spyOn之后调用带有函数引用的真实函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38252144/