2016-07-07 110 views
1

我有一个角度服务。在这个服务里面我有一个带有一个函数的对象,它引用了服务上的另一个函数。 (代码如下)Jasmine:用函数参考后调用spyOn后的实际函数

我想使用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

spyOn通过用不同的值替换对象属性的值来操作。当你做spyOn(service, "fooFunction");你正在做的一样

var realFunc = service.fooFunction; 
service.fooFunction = function() { 
    doSpyStuff(); 
    return realFunc.apply(this, arguments); 
} 

注意,这不修改值service.fooFunction的东西。它实际上修改了service - 即service的其中一个属性现在是完全不同的功能。此更换只会影响servicefooFunction财产。如果你没有访问service的属性,你当然不会调用间谍功能。

因此,让我们将这些知识应用于您的案例。在您的测试中,您访问的是service.bar的财产。尽管service.bar.barFunctionservice.fooFunction原本是相同的值,但service已将其fooFunction属性替换为间谍,而(非常重要的)service.bar没有将其任何属性突变spyOn。当你打电话给service.bar.barFunction()时,你直接调用真正的功能,并且与servicefooFunction属性上的间谍无法连接。

与此相反,当你做barFunction: function() { return self.fooFunction(); }作为一个匿名函数,你实际上访问上service间谍属性值,因为这里self恰好是service,所以self.fooFunctionservice.fooFunction,这是保持间谍财产重置价值。

+0

我想这是沿着这些线。无论如何要测试这些呢? – Mistrog

+0

@Mistrog你可以窥探属性,而不是函数值,所以你必须监视你想调用的确切对象/属性。或者,使用第二个例子中的模式。 – apsillers