web-dev-qa-db-fra.com

Angular2 unit testing: test du constructeur d'un composant

Tout est dans le titre: comment peut-on tester ce qui est fait dans le constructeur du composant?

Pour votre information, j'utilise un service qui nécessite un paramètre et j'aimerais voir si les 2 méthodes que j'appelle dans le constructeur sont appelées correctement. 

Le constructeur de mon composant: 

constructor(
  public router: Router,
  private profilService: ProfileService,
  private dragula: DragulaService,
  private alerter: AlertService
) {
  dragula.drag.subscribe((value) => {
    this.onDrag(value);
  });
  dragula.dragend.subscribe((value) => {
    this.onDragend(value);
  });
}
4
trichetriche

J'injecterais un faux service en utilisant le système DI, ce qui signifierait écrire les tests à peu près comme ceci:

describe('your component', () => {
  let fixture: ComponentFixture<YourComponent>;
  let fakeService;
  let dragSubject = new ReplaySubject(1);
  ...

  beforeEach(async(() => {
    fakeService = { 
      drag: dragSubject.asObservable(),
      ... 
    };

    TestBed.configureTestingModule({
      declarations: [YourComponent, ...],
      providers: [
        { provide: DragulaService, useValue: fakeService }, 
        ...
      ],
    });
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(YourComponent);
    fixture.detectChanges();
  });

  it('should do something when a drag event occurs', () => {
    dragSubject.next({ ... });
    fixture.detectChanges();
    ...
  });
});

Cela vous permet de déclencher des "événements de glisser" quand vous le souhaitez en appelant .next sur le sujet, ce qui force les abonnés des champs du service factice à être appelés. Vous pouvez ensuite faire des affirmations sur les résultats que vous attendez de cela.

Notez que vous n'avez pas besoin d'appeler vous-même constructor; cette méthode est appelée lorsque le système DI instancie votre composant, c’est-à-dire lorsque TestBed.createComponent est appelé.

Je vous recommanderais de ne pas espionner les méthodes de composant (par exemple, this.onDrag) et de vous assurer simplement qu'elles soient appelées, mais plutôt de vérifier que tout ce que ces méthodes devraient faire en conséquence se produit; cela rend les tests plus robustes aux modifications de la mise en œuvre spécifique (j'ai écrit un peu à ce sujet sur mon blog: http://blog.jonrshar.pe/2017/Apr/16/async-angular-tests.html ).

6
jonrsharpe

Le moyen le plus simple de tester quoi que ce soit dans la fonction constructeur est de créer une instance de composant, puis de la tester.

it('should call initializer function in constructor', () => {
  TestBed.createComponent(HomeComponent); // this is the trigger of constructor method
 expect(sideNavService.initialize).toHaveBeenCalled(); // sample jasmine spy based test case
});

Une chose à noter que, si vous voulez faire la distinction entre constructor et ngOnInit, n'appelez pas fixture.detectChanges() dans beforeEach(). appelez plutôt manuellement quand vous en avez besoin.

2

Puisque OP dit "Je voudrais voir si les 2 méthodes que j'appelle dans le constructeur sont appelées correctement." J'ai une meilleure approche.

Ecrivez un test unitaire. Vous n'avez pas besoin d'utiliser le banc d'essai pour cela. Cela ralentira beaucoup vos tests. Instanciez vos simulacres manuellement. Définissez vos espions sur les méthodes qui vous intéressent, puis appelez manuellement le constructeur du composant avec les boutons que vous avez instanciés et sur lesquels vous avez défini les espions. Puis testez si les méthodes espionnées ont été appelées correctement.

La clé est d'étendre vos stubs à partir des classes de service d'origine. jasmine.createSpyObj aide à se moquer des classes angulaires telles que Router.

0
aycanadal