2014-09-26 150 views
0

有可能是太多這類問題就在這裏,但沒有我發現想出一個好的解決方案。 在我看來,問題應該太常見了。 髒僞代碼: Acontroller角茉莉花(1.3)控制器模擬服務測試

app.controller('Acontroller',function($scope,$q, Aservice){ 

    $scope.someScopeVariable = null; 

    function refresh(){ 
    $q.all([ 
    Aservice.getCollectionA().then(function(results){ 
     return $scope.collectionA = results}), 
    Aservice.getCollectionB().then(function(results){ 
     return $scope.collectionB = results}) 
    ]); 
    }; 

    $scope.someScopeFunction = function(){ 
     Aservice.someServerUpdateCall().then(function(){ 
     refresh().then(function(){ 
      $scope.someScopeVariable = 'woot' 
     } 
     } 
    } 
}) 

這真的只是寫不好真的?我正在禿頭上剔除剩餘的頭髮,試圖測試someScopeFunction。

你怎麼測試呢? (茉莉(只佬1.3))

我可以測試承諾的第一梯隊,但我不能簡單地斷言刷新函數被調用。我可以嘲笑這項服務,但是我有一段時間讓這個刷新功能被窺探。我會假設我必須實例化控制器(找到類似的解決方案),儘管這似乎有點瘋狂。

所以(原諒的CoffeeScript):

describe 'Acontroller', -> 
    mockService = {} 
    aResponseObject = 
    a:1 
    b:2 
    beforeEach -> module('app') 

    beforeEach inject ($controller,$q, $rootScope) -> 

    emptyPromise = -> 
     defer = $q.defer 
     defer.resolve() 
     defer.promise 


    responsePromise = -> 
     defer = $q.defer() 
     defer.resolve([aResponseObject],[aResponseObject]) 
     defer.promise 

    mockService.getCollectionA = jasmine.createSpy('getCollectionA').andReturn responsePromise() 
    mockService.getCollectionB = jasmine.createSpy('getCollectionB').andReturn responsePromise() 
    mockService.someServerUpdateCall = jasmine.createSpy('someServerUpdateCall').andReturn emptyPromise() 
    scope = $rootScope.$new() 
    $controller 'Acontroller', 
     $scope: scope 
     Aservice: mockService 

    $rootScope.$apply ## resolve promises 

    describe 'someScopeFunction', -> 

    it 'should call Aservice with someServerUpdateCall', -> 

     scope.someScopeFunction() 
     scope.$digest 
     expect(Aservice.someSererUpdateCall).toHaveBeenCalled() ##this should work 

這種期望工作正常,雖然確認了下一次調用刷新就是我不知所措。看到它與範圍無關,我會假設我必須實例化控制器?

我已與其他戰略,包括像玩耍了:

done = false 
refresh = jasmine.createSpy('refresh') 

scope.someScopeFunction().then() -> done = true 

waitsFor -> done 

runs -> 
    scope.$apply -> 
    expect(refresh).toHaveBeenCalled() 

無濟於事雖然承諾沒有得到解決。

聽說摩卡使異步調用多一點簡單的,但我真的很害怕嘗試重新開始。

+1

哪裏是你的測試? – PSL 2014-09-26 23:51:45

回答

0

所以,我想我想通了。 我改變了作用域上的原始函數來代替注入refresh()函數。 然後在針對返回承諾的測試中注入間諜後,在範圍上調用$摘要。

$scope.someScopeFunction = (refreshFn=refresh) 
    Aservice.someServerUpdateCall().then -> 
    refreshFn().then -> 
     $scope.someScopeVariable = 'woot' 

測試將被:

describe 'Acontroller', -> 

    mockService = {} 
    mocks = {} 
    aResponseObject = 
    a:1 
    b:2 
    beforeEach -> module('app') 

    beforeEach inject ($controller,$q, $rootScope) -> 

    mocks.emptyPromise = -> 
     defer = $q.defer 
     defer.resolve() 
     defer.promise 


    mocks.responsePromise = -> 
     defer = $q.defer() 
     defer.resolve([aResponseObject],[aResponseObject]) 
     defer.promise 

    mockService.getCollectionA = jasmine.createSpy('getCollectionA').andReturn mocks.responsePromise() 
    mockService.getCollectionB = jasmine.createSpy('getCollectionB').andReturn mocks.responsePromise() 
    mockService.someServerUpdateCall = jasmine.createSpy('someServerUpdateCall').andReturn mocks.emptyPromise() 

    scope = $rootScope.$new() 

    $controller 'Acontroller', 
     $scope: scope 
     Aservice: mockService 

    $rootScope.$apply ## resolve promises 

    describe 'someScopeFunction', -> 

    it 'should call refresh() after someServerUpdateCall', -> 
     refresh = jasmine.createSpy('refresh').andReturn(mocks.emptyPromise()) 
     scope.someScopeFunction(refresh) 
     scope.$digest -> 
     expect(refresh).toHaveBeenCalled()