2015-07-03 30 views
6

我有一個方法在AngularJS控制器中定義,它在初始化時被調用。我想用Jasmine測試它("jasmine-core": "^2.3.4", "karma": "^0.12.37")。我遵循互聯網和StackOverflow問題的一些教程,但我找不到正確的答案。運行測試,該錯誤消息後茉莉花控制器測試,預計的間諜已被稱爲

(function() { 

    'use strict'; 

    describe('usersAddUserControllerUnitTest', function() { 
     var scope, deferred, objectUnderTest, mockedAddUserService; 

     beforeEach(module('app')); 

     beforeEach(inject(function ($rootScope, $q, $controller) { 
      scope = $rootScope.$new(); 

      function emptyPromise() { 
       deferred = $q.defer(); 
       return deferred.promise; 
      } 

      mockedAddUserService = { 
       getCountryPhoneCodes: emptyPromise 
      }; 

      objectUnderTest = $controller('usersAddUserController', { 
       $scope: scope, 
       usersAddUserService: mockedAddUserService 
      }); 
     })); 

     it('should call getCountryPhoneCodes method on init', function() { 
      //when    
      spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough(); 

      deferred.resolve(); 

      scope.$root.$digest(); 

      //then 
      expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled(); 
     }); 

    }); 
}()); 

:請看看這段代碼:

控制器​​93:

(function() { 
    'use strict'; 

    angular.module('app.users.addUser') 
     .controller('usersAddUserController', ['$scope', 'usersAddUserService', function ($scope, usersAddUserService) { 

      usersAddUserService.getCountryPhoneCodes().then(function (phoneCodes) { 
       $scope.phoneCodes = phoneCodes; 
      }); 

     }]); 
}()); 

茉莉花測試

PhantomJS 1.9.8 (Windows 7 0.0.0) usersAddUserControllerUnitTest should call getCountryPhoneCodes method on init FAILED

Expected spy getCountryPhoneCodes to have been called. 

我顯然錯過了一些東西,但我無法弄清楚它是什麼。任何幫助將不勝感激。

回答

3

你刺探在它被傳遞到實例化的控制器後的模擬。

試試這個:

describe('usersAddUserControllerUnitTest', function() { 
    var scope, deferred, objectUnderTest, mockedAddUserService, $controller; 

    beforeEach(module('app')); 

    beforeEach(inject(function ($rootScope, $q, _$controller_) { 
     scope = $rootScope.$new(); 

     function emptyPromise() { 
      deferred = $q.defer(); 
      return deferred.promise; 
     } 

     mockedAddUserService = { 
      getCountryPhoneCodes: emptyPromise 
     }; 

     $controller = _$controller_; 
    })); 

    function makeController() {  
     objectUnderTest = $controller('usersAddUserController', { 
      $scope: scope, 
      usersAddUserService: mockedAddUserService 
     }); 
    } 

    it('should call getCountryPhoneCodes method on init', function() { 
     //when 

     spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough(); 
     makeController(); 

     deferred.resolve(); 

     scope.$root.$digest(); 

     //then 
     expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled(); 
    }); 

}); 

編輯感謝@juunas在我的解決方案

+0

感謝您的回答,但不幸的是,您的代碼仍然會出現同樣的錯誤。它對你有用嗎? –

+0

我沒有真正嘗試過,它看起來像是一個明顯的問題。你可以在你的控制器構造函數上放一個斷點,看看它是否真的是它調用的間諜? – Martin

+0

非常感謝你們!事實上,@尤納斯是對的,我現在得到了成功。如果juunas同意,我會接受馬丁的答案,無論如何,它可以幫助我很多:) –

1

您可以提供這樣的模擬:

mockedAddUserService = { 
    getCountryPhoneCodes: emptyPromise 
}; 


beforeEach(function() { 
    module(function ($provide) { 
     $provide.value('usersAddUserService', mockedAddUserService); 
    }); 
}); 

編輯:

代碼應該如下(我不能測試它)是這樣的:

(function() { 
    'use strict'; 

    describe('usersAddUserControllerUnitTest', function() {   
     beforeEach(module('app')); 

     var emptyPromise = function() { 
      var deferred = $q.defer(); 
      return deferred.promise; 
     } 

     var mockedAddUserService = { 
      getCountryPhoneCodes: emptyPromise 
     }; 

     beforeEach(function() { 
      module(function ($provide) { 
       $provide.value('usersAddUserService', mockedAddUserService); 
      }); 
     }); 

     var scope; 
     beforeEach(inject(function ($rootScope, $q, $controller) { 
      scope = $rootScope.$new(); 
      $controller('usersAddUserController', { 
       $scope: scope 
      }); 
     })); 

     it('should call getCountryPhoneCodes method on init', function() { 
      spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough(); 

      scope.$root.$digest(); 

      expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled(); 
     }); 

    }); 
}()); 
+0

謝謝你的答案注意到這個錯誤,但你能提供完整的代碼?當我將你的解決方案包含在代碼中時,我得到:「TypeError:'undefined'不是一個對象(評估'deferred.resolve')」。 –

+0

謝謝你的代碼,我會嘗試你的解決方案,並給出一個反饋,需要做更多的事情。 –