Jasmine:在带有函数引用的 spyOn 之后调用的真实函数
Jasmine: Real function being called after spyOn with function reference
我有一个 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
的 属性,那么您肯定不会调用间谍功能。
所以让我们将这些知识应用到您的案例中。在您的测试中,您正在访问 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
是service.fooFunction
,也就是持有间谍替换值的属性。
我有一个 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
的 属性,那么您肯定不会调用间谍功能。
所以让我们将这些知识应用到您的案例中。在您的测试中,您正在访问 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
是service.fooFunction
,也就是持有间谍替换值的属性。