2016-02-02 83 views
-1

我正在測試'ServiceOne',它在第二個服務「ServiceTwo」中使用了一個名爲「get」的方法。 'ServiceTwo'中的get()方法調用$http,所以它會返回一個承諾,直到解析$http調用。該「ServiceOne」的方法,我試圖測試如下:AngularJS單元測試:模擬的承諾已解決,但方法仍然返回一個承諾?

serviceOne.getNewId = function (oldId) { 
    var url = "http://mock.com"; 

    return serviceTwo.get(url).then(function (returned) { 
     if (returned.data !== undefined) { 
      return returned.data[0].newId; 
     } else { 
      return oldId; 
     } 
    }); 
}; 

這是我在ServiceOne測試getNewId()

beforeEach(angular.mock.inject(function (_serviceOne_,_$q_, _$rootScope_, _serviceTwo_) { 

    serviceOne = _serviceOne_; 
    serviceTwo = _serviceTwo_; 

    $rootScope = _$rootScope_; 
    deferred = _$q_.defer(); 
})); 

it('should return a newId', inject(function (serviceTwo) {   
    spyOn(serviceTwo, 'get').and.returnValue(deferred.promise); 

    var returnedData = {data:[{newId: '95'}]}; 
    deferred.resolve(returnedData); 

    var retVal = serviceOne.getNewId('322');  
    $rootScope.$apply(); 

    expect(retVal).toBe('95'); //fails 
})); 

retVal正在返回一個承諾對象,而不是預期的字符串'95'。所以,我可以讓我的測試通過,如果我進入了承諾目標,並尋找價值:

expect(retVal.$$state.value).toBe('95'); //passes 

返回的承諾對象具有1的狀態,所以我知道它已經解決了。並且promise的值是正確的,設置爲'95',就好像我的then()函數內的邏輯已經被執行一樣。爲什麼當我運行Karma時會收到此錯誤消息?

Expected Promise({ $$state: Object({ status: 1, value: '95' }) }) to be '95'. 

回答

1
與承諾他們不返回值

因此,他們返回一個承諾,所以你必須調整你的測試是這樣的:

it('should return a newId', inject(function (serviceTwo) {   
    spyOn(serviceTwo, 'get').and.returnValue(deferred.promise); 

    var returnedData = {data:[{newId: '95'}]}; 
    var retVal; 

    serviceOne.getNewId('322') 
     .then(function(result){ 
      retVal = result; 
     }); 

    deferred.resolve(returnedData); 

    $rootScope.$apply(); 

    expect(retVal).toBe('95'); //should pass 
})); 
+0

這完美地工作,非常感謝你的幫助! – user3897392