2016-07-07 70 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