2016-12-17 253 views
0

我在我的控制器以下功能:

function putActivities() { 
    var promises = []; 
    view.activities.forEach(function (activity) { 
     promises.push(API.putActivities({activity: activity}).$promise); 
    }); 
    $q.all(promises).then(function() { 
     view.finished = true; 
    }); 
} 

,其中API是$資源。這種方法是通過下面的代碼片段測試:

describe('putActivities', function() { 
    beforeEach(function() { 
     view.activities = ['hello']; 
     spyOn(API, 'putActivities').and.callFake(function() { 
      return { 
       $promise: q(function() {}) 
      } 
     }); 
    }); 
    it('view is finished after putting activities', function() { 
     view.putActivities(); 
     expect(view.finished).toEqual(true); 
    }); 
}); 

出於某種原因,$ q.all從未解析和view.finished永遠不會設置爲true。有誰知道爲什麼會發生這種情況,以及我如何解決這個問題?

回答

1

間諜正在返回的假承諾需要手動解決(或拒絕)。

不知道什麼間諜的q功能呢,但我會在本例中使用Angular's $q

beforeEach(function() { 

    view.activities = ['hello']; 
    mockedPromises = []; 

    spyOn(API, 'putActivities').and.callFake(function() { 

    var defer = $q.defer(); 
    mockedPromises.push(defer); 

    return { 
     $promise: defer.promise 
    }; 
    }); 
}); 

現在你有機會獲得在測試中的承諾,既可以解決或拒絕其中,具體取決於哪個方案要測試:

it('view is finished after putting activities', function() { 

    view.putActivities(); 

    mockedPromises.forEach(function(promise) { 
    promise.resolve(); 
    }); 

    $rootScope.$apply(); 

    expect(view.finished).toEqual(true); 
}); 

注意,測試時承諾(至少與$q服務),承諾的分辨率是聯繫在一起的消化週期,這意味着then函數只有在摘要運行後纔會調用。

測試時需要手動觸發摘要循環(因此您可以更好地控制流程)。這就是$rootScope.$apply()所做的。

+0

我在某個時候嘗試了這一點 - 但沒有繼續這個,因爲它給了我另一個異常,'錯誤:意外的請求:GET http:// localhost/api/endpoint。沒有更多的預期要求。在控制器的init方法中有一個不同的API調用,它必須由$ rootScope。$ apply調用(它也出現在$ rootScope。$ digest中)。我試圖監視其他端點,但沒有解決錯誤。 – cscan

+0

您需要通過'$ httpBackend'預期請求。請參閱https://docs.angularjs.org/api/ngMock/service/$httpBackend – tasseKATT