2013-12-14 95 views
2

我有這個方法返回一個承諾,也利用了另外兩個承諾的內部:單元測試承諾在AngularJS

this.getLocation = function() { 
    var deferred = $q.defer(); 
    var that = this; 

    this.getCoords().then(function(coords) { 
     var result = {}; 
     result.coords = coords; 

     that.coordsToAddress(coords).success(function(address) { 

     result.address = address; 
     deferred.resolve(result); 

     }).error(function() { 
     deferred.reject('Unable to request coords to address'); 
     }); 
    }, function(reason) { 
     deferred.reject(reason); 
    }); 

    return deferred.promise; 
    }; 

由於兩個承諾被調用的函數內屬於不同的模塊,並有自己的自己的測試,我只是想測試this.getCoords()this.coordsToAddress()被調用。

我設置我的間諜:

spyOn(Googlemaps, 'getCoords').andCallThrough(); 
spyOn(Googlemaps, 'coordsToAddress').andCallThrough(); 

寫了這樣的測試:

describe('getLocation()', function() { 

    beforeEach(function() { 
     Googlemaps.getLocation(); 
    }); 

    it('should call getCoords()', function() { 
     expect(Googlemaps.getCoords).toHaveBeenCalled(); 
    }); 

    it('should call coordsToAddress()', function() { 
     expect(Googlemaps.coordsToAddress).toHaveBeenCalled(); 
    }); 

    }); 

第一個成功,而最後一個失敗:

Expected spy coordsToAddress to have been called. 

我的猜測是我需要滿足getCoords()的承諾才能調用coordsToAddress()。我怎樣才能做到這一點?在檢查coordsToAddress()被調用之前,我嘗試使用$rootScope.$spply()觸發摘要。

+0

我在打電話,所以我不能給出確切的答案。但是,如果您使用getColt()作爲getColt()間諜而不是andCallThrough(),則可以使假函數(您編寫的)返回一個承諾,然後您可以解決該問題... –

回答

3

這真的取決於你在這裏試圖完成什麼。如果您確實需要進行異步呼叫,則需要調查更多關於Jasmine and async的信息。

如果您只是想驗證函數正在被調用,可以通過使用.andReturn來嘲笑異步調用來阻止異步調用。

所以嘲諷將是這樣的:

var coord = $q.defer().promise; 
spyOn(Googlemaps, 'getCoords').andReturn(coord.resolve(yourMockCoords)); 

var toAdd = $q.defer().promise; 
spyOn(Googlemaps, 'coordsToAddress').andReturn(toAdd.resolve(yourAddress)); 

這將讓你沒有做任何Ajax調用,只是驗證您的通話是否正常工作。