AngularJS测试在promise中调用了promise

时间:2013-12-14 13:47:08

标签: unit-testing angularjs karma-runner

我在服务中使用此方法:

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

  geolocation.getLocation().then(function(data) { // line 29 in Karma output
    var coords = _.pick(data.coords, 'latitude', 'longitude');
    return deferred.resolve(coords);
  }, function(reason) {
    return deferred.reject(reason);
  });

  return deferred.promise;
};

由于geolocation本身就是一个模块,我只想测试geolocation.getLocation()承诺确实已被调用。

到目前为止我做了什么:

 ...

 geolocationGetLocationSpy = spyOn(geolocation, 'getLocation');

 ...

 describe('getCoords()', function() {

   it('should call geolocation.getLocation()', function() {
     Googlemaps.getCoords(); // line 64 in Karma output

     // promise won't get resolved until a digest
     $rootScope.$apply();

     expect(geolocationGetLocationSpy).toHaveBeenCalled();
   });

 });

但是我得到了:

PhantomJS 1.9.2 (Mac OS X) Service: Googlemaps getCoords() should call geolocation.getLocation() FAILED
    TypeError: 'undefined' is not an object (evaluating 'geolocation.getLocation().then')
        at /Users/jviotti/Projects/Temporal/angular/angular-geolocation/app/scripts/services/googleMaps.js:29
        at /Users/jviotti/Projects/Temporal/angular/angular-geolocation/test/spec/services/googleMaps.js:64

我还应该做些什么?

1 个答案:

答案 0 :(得分:7)

你使用的模式看起来很好。试着这样做:

geolocationGetLocationSpy = spyOn(geolocation, 'getLocation').andCallThrough();

// or the Jasmine 2.0 syntax
geolocationGetLocationSpy = spyOn(geolocation, 'getLocation').and.callThrough();

当您监视某个方法时,原始方法会被一个使所有“间谍”功能都起作用的方法覆盖。虚假版getLocation()未返回与原始方法相同的值(原始方法似乎返回promise)。

为此,您可以添加andCallThrough(),现在虚假版getLocation()将调用原始方法以及执行“间谍”功能。