2016-11-15 34 views
0

嗯,我花了一天左右的時間尋找解決方案,我不知道我是誰的智者,所以我分手了,並決定問。另外,我對角度相當陌生,因此非常感謝耐心。

我有一個服務,定期從控制器調用從遠程服務器檢索更新的評判分數。相當標準的東西。只有相關代碼顯示 - 沒有錯誤處理程序和時間間隔取消等

$app.service('ResultService', function($http) { 
     var self = this; 
     self.results = {}; 

     self.getResults = function() { 

      return $http.get('/results').then(function(response) { 
       return $q.when(response.data).then(function(data) { 
        angular.copy(self.results, response.data); 
       }; 
      }; 

     }; 
    }); 

    $app.controller('ResultController', function($interval, resultService) { 
     var vm = this; 

     $interval(function() { 
      resultService.getResults().then(function(data) { 
       vm.results = data; 
      }); 
     }, 1000); 
    }); 

都好,到目前爲止,並根據需要在瀏覽器中一切正常。

現在進行測試。我想驗證更新是否被getResults函數接收和處理,但是我正在努力執行必要的小雞犧牲以導致延遲被多次使用。我以爲我可以做這樣的事情:

var deferred; 
beforeEach(inject(function($q, httpBackend) { 
    deferred = $q.defer(); 
    httpBackend.whenGET('/results').respond(deferred.promise); 
}); 

it('updates results', inject(function($interval) { 
    deferred.resolve({some: 'data'}); 
    scope.$digest(); 
    httpBackend.flush(); 
    $interval.flush(1200); 
    // This works fine 
    expect(resultsService.results).toEqual({some: 'data'}); 

    deferred.resolve({other: 'data'}); 
    scope.$digest(); 
    httpBackend.flush(); 
    $interval.flush(1200); 
    // But this of course does not. 
    expect(resultsService.results).toEqual({other: 'data'}); // fails 
}); 

現在看來,延期的承諾只能解決一次。所以我的問題是,如何在每次測試的迭代中爲服務的$ http.get()調用提供新的數據?我嘗試了各種各樣的東西,都沒有成功:

  • 創建了一個延期,它本身返回了延期承諾。這樣瘋狂的謊言。
  • 試圖用新的響應重新設置httpBackend.whenGET()。這沒有效果。
  • 在區間迭代之間的測試中創建了一個新的延遲。不用說這失敗了,因爲原先的延期承諾已經建立起來了。
  • 從whenGET()返回一個靜態值,並直接操作該值。不幸的是,雖然這個「有效」,但它似乎相當黑客,並導致另一個測試(預計拒絕)失敗。

那麼我錯過了什麼?這裏有什麼竅門?我接受替代解決方案(不使用延遲)以及任何能夠按原樣從代碼中清除我的眼睛的任何東西。

回答

0

不太確定,但沒有人回覆。

策略:

  • 限定data陣列與一個模擬數據集爲每個數組元素。
  • 利用data.reduce()模式測試異步序列中的每個模擬數據集。
  • 隨着序列的進展在數組中累積結果。
  • 在收集所有結果時異步執行單個expect() - 應該等於原始的data數組。
it('updates results', inject(function($interval) { 
    var dataArray = [ 
     {some: 'data'}, 
     {other: 'data'} 
    ] 
    data.reduce(function(promise, data) { 
     return promise.then(function(resultsArray) { 
      // *** not sure about this section - I just copied and pasted *** 
      deferred.resolve(data); 
      scope.$digest(); 
      httpBackend.flush(); 
      $interval.flush(1200); 
      // *** ****************************************************** *** 
      return resultsArray.concat(resultsService.results); 
     }); 
    }, deferred.resolve([])) // starter promise resolved with an empty results array. 
    .then(function(results) { 
     expect(results).toEqual(dataArray); 
    }); 
}); 

很可能不是100%正確的,但可能會刺激進一步的想法。