7 votes

AngularJS injecter le service mock dans les tests de service

J'essaie de tester un service sans succès depuis un certain temps et j'espérais obtenir de l'aide. Voici ma situation :

J'ai un service qui ressemble un peu à ceci

myModule.factory('myService', ['$rootScope', '$routeParams', '$location', function($rootScope, $routeParams, $location) {

  var mySvc = {
    params: {}
  }

  // Listen to route changes.
  $rootScope.$on('$routeUpdate', mySvc.updateHandler);

  // Update @params when route changes
  mySvc.updateHandler = function(){ ... };

  ...
  ...

  return mySvc;

}]);

Et je veux faire un simulacre des services injectés dans 'myService' avant que le service ne soit injecté dans mes tests afin que je puisse tester la code d'initialisation en dessous de

  var mySvc = {
    params: {}
  }

  // Listen to route changes.
  $rootScope.$on('$routeUpdate', mySvc.updateHandler);

J'utilise Jasmine pour les tests et les mocks. Voici ce que j'ai trouvé pour l'instant

describe('myService', function(){
  var rootScope, target;
  beforeEach(function(){
    rootScope = jasmine.createSpyObj('rootScope', ['$on']);

    module('myModule');
    angular.module('Mocks', []).service('$rootScope', rootScope );
    inject(function(myService){
      target = myService;
    });        
  });

  it('should be defined', function(){
    expect(target).toBeDefined();
  });

  it('should have an empty list of params', function(){
    expect(target.params).toEqual({});
  });

  it('should have called rootScope.$on', function(){
    expect(rootScope.$on).toHaveBeenCalled();
  });
});

Mais ça ne marche pas. Ma maquette de rootscope ne remplace pas l'original et la documentation sur l'injection de dépendances m'embrouille plus que tout.

Veuillez m'aider

7voto

Guillaume Babin Points 116

J'espionnerais le $rootScope réel au lieu d'essayer d'injecter votre propre objet personnalisé.

var target, rootScope;
beforeEach(inject(function($rootScope) {
  rootScope = $rootScope;

  // Mock everything here
  spyOn(rootScope, "$on")
}));

beforeEach(inject(function(myService) {
  target = myService;
}));

it('should have called rootScope.$on', function(){
  expect(rootScope.$on).toHaveBeenCalled();
});

J'ai testé cela en CoffeScript, mais le code ci-dessus devrait toujours fonctionner.

0voto

felipekm Points 2636

Vous pourriez créer un RootController, puis l'injecter :

inject(function(myService, $controller){
  target = myService;
  $controller('rootController', {
        $scope : $rootScope.$new(),
        $rootScope : myService
  });
});  

Avec cette approche, vous pouvez accéder aux fonctions de $rootScope à partir de votre 'myService' ; tel que 'myService.$on()'.

Je viens de le faire, faites-moi savoir si vous avez besoin d'aide.

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