【问题标题】:Angular unit test a service return Promise JasmineAngular 单元测试服务返回 Promise Jasmine
【发布时间】:2018-02-09 21:26:45
【问题描述】:

我跟随 this tutorial 对返回 aPromise 但无法正常工作的服务进行单元测试。

我的服务返回一个Promise,它将检索HTML5 地理位置。

app.factory('getGeo', function() { 
     return function(){
         return new Promise(function (resolve, reject) {
         navigator.geolocation.getCurrentPosition(resolve, reject, options);
          });        
       }
      var options = {
         enableHighAccuracy: true,
         timeout: 5000,
          maximumAge: 0
          };         
});

我的控制器有一个函数可以解析Promise 以在应用程序中设置一些状态。

getGeo().then((position) => {
          //perform logic when geo is received
          $scope.weatherInfo.la = position.coords.latitude;//new properties
          $scope.weatherInfo.lo = position.coords.longitude;//new properties
          $scope.weatherInfo.url = `http://api.openweathermap.org/data/2.5/weather?lat=${$scope.weatherInfo.la}&lon=${$scope.weatherInfo.lo}&appid=0d00180d180f48b832ffe7d9179d40c4`;
        })

我的测试:

beforeEach(inject(function(_$rootScope_, _getGeo_){
   $rootScope = _$rootScope_;
   $getGeo = _getGeo_;
 }));

describe('getGeo method', function() {
  it('getGeo should return a promise', function() {
    var $scope = $rootScope.$new();
    var position = {coords:{coords:{latitude:'1',latitude:'3'}}};
    $getGeo().then(function(position) {
    expect($scope.weatherInfo.url).not.toBeNull();
    done();
   });
   $scope.$digest();                
 });
});

我收到了这个SPEC HAS NO EXPECTATIONS getGeo should return a promise。似乎模拟服务中的代码永远不会被调用。但如果我将expect($scope.weatherInfo.url).not.toBeNull() 移出并放在$scope.$digest() 下,我会收到Cannot read property 'url' of undefined 错误。

【问题讨论】:

    标签: javascript angularjs unit-testing promise jasmine


    【解决方案1】:
    1. var position = {coords:{coords:{latitude:'1',latitude:'3'}}}; $getGeo().then(function(position) { expect($scope.weatherInfo.url).not.toBeNull(); }

    回调变量 - 它是承诺将返回的数据。不是你的var position = {coords:{coords:{latitude:'1',latitude:'3'}}};

    1. 我认为你不应该在测试中打电话给工厂。当您第一次注入工厂时,工厂只会调用一次构造函数。 所以你只需要制作下一个

      $getGeo.then(function(position) {...})

    2. 您的工厂从外部navigator.geolocation.getCurrentPosition() 获取数据。所以你需要为它制作存根。

      spyOn(navigator.geolocation, 'getCurrentPosition').andReturn(/* here is the data which you expected */)

    很难向您展示完整的示例。但是,我试图描述关键的事情。

    【讨论】:

    • 感谢@NechiK 的回答,我不太清楚这句话是什么意思 --- 所以你只需要做下一个$getGeo.then(function(position) {...})。这是否意味着我需要省略此代码,因为我不想调用工厂?
    • var position = {coords:{coords:{latitude:'1',latitude:'3'}}}; spyOn(navigator.geolocation, 'getCurrentPosition').and.returnValue(position); $getGeo() 这也不起作用。
    • 我认为你不应该调用工厂函数。它将自动初始化。我将创建您提供的代码示例,但不幸的是,我现在很忙。我将尝试在 1 天内完成。也许我会为你提供解决方案
    猜你喜欢
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多