Jasmine:使用函数引用

时间:2016-07-07 17:52:41

标签: javascript angularjs unit-testing jasmine spy

我有一个有角度的服务。在这个服务中,我有一个带有函数的对象,它引用了服务上的另一个函数。 (以下代码)

我想使用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的哪个部分?

1 个答案:

答案 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.barservice.bar.barFunction最初是相同的值,但service.fooFunction已将其service属性替换为间谍,而(非常重要的)fooFunction尚未拥有由service.bar变异的任何属性。当您致电spyOn时,您直接调用真实函数,并且与service.bar.barFunction() service财产上的间谍无关。

相比之下,当您fooFunction作为匿名函数执行时,您实际上 访问barFunction: function() { return self.fooFunction(); }上的间谍属性值,因为此处service恰好是self,因此serviceself.fooFunction,这是保存间谍重置价值的属性。