2013-12-14 143 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调用,只是验证您的通话是否正常工作。