AngularJS中的单元测试承诺

时间:2013-12-14 23:09:47

标签: unit-testing angularjs jasmine

我有这个方法返回一个promise并且还在内部使用其他两个promise:

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;
  };

由于在函数内部调用的两个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()。我怎样才能做到这一点?在检查$rootScope.$spply()被调用之前,我尝试使用coordsToAddress()触发摘要。

1 个答案:

答案 0 :(得分: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调用,只需验证您的呼叫是否正常工作。