114 votes

Injectant une maquette dans un service de AngularJS

J'ai un service AngularJS service de l'écrit et de voudrais de test de l'unité.

angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
    factory('myService', function ($http, fooService, barService) {

    this.somthing = function() {
        // Do something with the injected services
    };

    return this;
});

Mon app.js fichier a ces enregistré:

angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)

Je peux tester les DI travaille en tant que tel:

describe("Using the DI framework", function() {
    beforeEach(module('fooServiceProvider'));
    beforeEach(module('barServiceProvider'));
    beforeEach(module('myServiceProvder'));

    var service;

    beforeEach(inject(function(fooService, barService, myService) {
        service=myService;
    }));

    it("can be instantiated", function() {
        expect(service).not.toBeNull();
    });
});

Cela s'est avéré que le service peut être créé par le DI-cadre, toutefois prochaine je veux unité de tester le service, ce qui signifie se moquant de la injecté des objets.

Comment dois-je faire?

J'ai essayé de mettre mes objets fantaisie dans le module, par exemple

beforeEach(module(mockNavigationService));

et la réécriture de la définition du service:

function MyService(http, fooService, barService) {
    this.somthing = function() {
        // Do something with the injected services
    };
});

angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
    factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })

Mais ce dernier semble arrêter le service créé par le DI comme tous.

Quelqu'un sait comment je peut se moquer de l'injection de services pour mes tests unitaires?

Merci

David

182voto

John Galambos Points 563

Vous pouvez insérer des objets fantaisie dans votre service à l'aide de $provide.

Si vous avez le service suivant avec une dépendance qui a une méthode appelée getSomething:

angular.module('myModule')
  .factory('myService', function (myDependency) {
        return {
            useDependency: function () {
                return myDependency.getSomething();
            }
        };
  });

Vous pouvez injecter une version fantaisie de myDependency comme suit:

describe('Service: myService', function () {

  var myService,
      mockDependency;

  beforeEach(module('myModule'));

  beforeEach(function () {

      mockDependency = {
          getSomething: function () {
              return 'mockReturnValue';
          }
      };

      module(function ($provide) {
          $provide.value('myDependency', mockDependency);
      });

  });

  it('should return value from mock dependency', inject(function (myService) {
      expect(myService.useDependency()).toBe('mockReturnValue');
  }));

});

A noter qu'en raison de l'appel à $provide.value vous n'avez pas réellement besoin explicitement injecter myDependency n'importe où. Il arrive sous le capot lors de l'injection de myService. Lors de la configuration de mockDependency ici, il pourrait tout aussi facilement être un espion.

Grâce à loyalBrown pour le lien vers cette vidéo.

12voto

loyalBrown Points 424

Voici une superbe vidéo pour se moquer de services avec des dépendances dans AngularJS en utilisant l’infrastructure de test Jasmine. http://www.youtube.com/watch?v=QK-Z0oEdE4Y&feature=player_embedded

4voto

dnc253 Points 11784

La façon dont je regarde, il n'y a pas besoin de se moquer des services eux-mêmes. Tout simplement se moquer de l'fonctions sur le service. De cette façon, vous pouvez avoir angulaire de l'injecter, de services, comme il le fait dans toute l'application. Puis, se moquent de l'fonctions sur le service au besoin à l'aide de Jasmine spyOn fonction.

Maintenant, si le service lui-même est une fonction et non un objet que vous pouvez utiliser spyOn , il y a une autre façon d'aller à ce sujet. J'avais besoin de le faire, et trouvé quelque chose qui fonctionne assez bien pour moi. Voir Comment vous vous moquez Angulaire de service qui est une fonction?

1voto

CodingWithSpike Points 17720

Si votre contrôleur est écrit de prendre dans une dépendance comme ceci :

alors vous pouvez faire un faux `` dans une Jasmine test comme ceci :

1voto

Emil van Galen Points 66

J'ai récemment publié ngImprovedTesting qui devrait faire de la maquette de test dans AngularJS façon plus facile.

Pour tester 'myService" (à partir de la "myApp" module) avec ses fooService et barService dépendances moqué de vous simple pouvez effectuer les opérations suivantes dans votre Jasmin test:

beforeEach(ModuleBuilder
    .forModule('myApp')
    .serviceWithMocksFor('myService', 'fooService', 'barService')
    .build());

Pour plus d'informations sur ngImprovedTesting découvrez son introduction post de blog: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/

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