2015-07-03 2 views
6

Ich habe eine Methode in AngularJS-Controller definiert, die Initialisierung aufgerufen wird. Ich möchte es mit Jasmine ("jasmine-core": "^2.3.4", "karma": "^0.12.37") testen. Ich folge einigen Tutorials im Internet und StackOverflow Fragen, aber ich kann nicht die richtige Antwort finden. Bitte werfen Sie einen Blick auf diesen Code:Jasmin-Controller testen, erwartet Spion

-Controller usersAddUserController:

(function() { 
    'use strict'; 

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

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

     }]); 
}()); 

Jasmin-Test:

(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(); 
     }); 

    }); 
}()); 

Nach der Durchführung der Tests, die Fehlermeldung:

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

Expected spy getCountryPhoneCodes to have been called. 

I offensichtlich fehlt etwas, aber ich kann nicht herausfinden, was es ist. Jede Hilfe wird geschätzt.

Antwort

3

Sie spionieren:

Der Code sollte wie folgt aussehen (wie ich es nicht testen) der Schein, nachdem er in den instanziierten Controller übertragen wurde.

Versuchen Sie folgendes:

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(); 
    }); 

}); 

EDIT Dank @juunas für bemerkt den Fehler in meiner Lösung

+0

Vielen Dank für die Antwort, aber leider immer noch den gleichen Fehler mit Ihrem Code. Funktioniert es für dich? –

+0

Ich habe es nicht wirklich versucht, es sah einfach nach dem offensichtlichen Problem aus. Kannst du einen Haltepunkt auf deinen Controller-Konstruktor setzen und sehen, ob es tatsächlich der Spion ist, den er aufruft? – Martin

+0

Vielen Dank Jungs! Tatsächlich hatte @juunas recht, ich habe jetzt den ERFOLG bekommen. Wenn die Jugendlichen zustimmen, werde ich Martins Antwort trotzdem akzeptieren, es hilft mir sehr :) –

1

Sie die Mock wie diese zur Verfügung stellen kann:

mockedAddUserService = { 
    getCountryPhoneCodes: emptyPromise 
}; 


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

EDIT:

(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

Danke für die Antwort, aber könnten Sie vollständige Code zur Verfügung stellen? Wenn ich Ihre Lösung in meinen Code einfüge, bekomme ich: "TypeError: 'undefined' ist kein Objekt (Bewertung von 'deferred.resolve')". –

+0

Vielen Dank für den Code, ich werde Ihre Lösung auch versuchen und geben Sie eine Rückmeldung, was mehr getan werden muss. –