107 votes

Comment tester un service AngularJS avec Jasmine?

(Il est question ici: Jasmin test ne permet pas de voir AngularJS module)

Je veux juste tester un service sans amorçage Angulaire.

J'ai regarder quelques exemples et le tutoriel mais je ne vais pas n'importe où.

J'ai juste trois fichiers:

  • myService.js: où je définir un service AngularJS

  • test_myService.js: où je définir un Jasmin test pour le service.

  • specRunner.html: un fichier HTML avec la normale de jasmin de configuration et où je peux importer les deux autres fichiers et le Jasmin, Angularjs et angular-mocks.js.

C'est le code pour le service (qui fonctionne comme prévu lorsque je ne suis pas de test):

var myModule = angular.module('myModule', []);

myModule.factory('myService', function(){

    var serviceImplementation   = {};
    serviceImplementation.one   = 1;
    serviceImplementation.two   = 2;
    serviceImplementation.three = 3;

    return serviceImplementation

});

Comme je suis en train de tester le service dans l'isolement, je devrais être en mesure d'accéder et de vérifier leurs méthodes. Ma question est: comment puis-je injecter le service dans mon test sans amorçage AngularJS?

Par exemple, comment puis-je tester la valeur retournée par une méthode du service avec le Jasmin comme ceci:

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){
            myModule = angular.module('myModule');
                    //something is missing here..
            expect( myService.one ).toEqual(1);
        })

    }

});

Merci à l'avance.

137voto

Robert Points 4974

Le problème est que la méthode de fabrique, qui instancient le service, n'est pas appelé dans l'exemple ci-dessus (uniquement de la création du module n'est pas instancier le service).

Pour que le service soit instancié angulaire.l'injecteur doit être appelée avec le module où notre service est défini. Ensuite, nous pouvons demander à la nouvelle de l'injecteur objet pour le service et ses alors seulement lorsque le service est enfin instancié.

Quelque chose comme ceci fonctionne:

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){
            var $injector = angular.injector([ 'myModule' ]);
            var myService = $injector.get( 'myService' );
            expect( myService.one ).toEqual(1);
        })

    }

});

Une autre façon serait de passer au service d'une fonction à l'aide de 'appeler':

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){

            myTestFunction = function(aService){
                expect( aService.one ).toEqual(1);
            }

            //we only need the following line if the name of the 
            //parameter in myTestFunction is not 'myService' or if
            //the code is going to be minify.
            myTestFunction.$inject = [ 'myService' ];

            var myInjector = angular.injector([ 'myModule' ]);
            myInjector.invoke( myTestFunction );
        })

    }

});

Et, enfin, la "bonne" façon de le faire est d'utiliser les"injecter"et"module"dans un"beforeEachjasmine bloc. Lorsque vous faites cela, nous devons réaliser que les "injecter" la fonction, il n'est pas dans la norme, angularjs, mais dans le ngMock module et qu'il ne fonctionne qu'avec le jasmin.

describe('myService test', function(){
    describe('when I call myService.one', function(){
        beforeEach(module('myModule'));
        it('returns 1', inject(function(myService){ //parameter name = service name

            expect( myService.one ).toEqual(1);

        }))

    }

});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X