3 votes

Comment écrire un test unitaire pour l'abonnement ActionsSubject dans un composant Angular ?

J'ai un composant Angular qui utilise ngrx ActionsSubject pour écouter les actions envoyées. Comment puis-je écrire un test qui peut vérifier cet abonnement de ActionsSubject ?

Le composant se présente comme suit :

export class TestComponent {

constructor(public actionsSubject: ActionsSubject) { }

  public isUpdated = false;

  public ngOnInit() {
    this.actionSubscription = this.actionsSubject.subscribe(action => {
      if (action.type === "Update") {
        this.isUpdated = true; <----- I want to test this condition
      }
    });
  }
}

Actuellement, j'envoie l'action de mise à jour manuellement :

  it('isUpdated should be true, when update action dispatched', () => {
    component.store.dispatch(new UpdateAction());
    expect(component.isUpdated).toEqual(true);
  });

Cela fonctionne, mais je veux simuler cet abonnement au lieu d'appeler l'action manuellement.

Par exemple :

  it('isUpdated should be true, when update action dispatched', () => {
    let actionSubject = TestBed.get(ActionsSubject);
    const action = {
      type: 'Update'
    };
    actionSubject = of({ action });
    component.ngOnInit();
    fixture.detectChanges()
    expect(component.isUpdated).toEqual(true);
  });

La combinaison d'essai ressemble à ceci

const action = { type: FlowActionTypes.UpdateStep }; 
const actionSub: ActionsSubject = new ActionsSubject({ action }); <-- TS not accepting 

providers: [ { provide: ActionsSubject, useValue: actionSub } <-- here I am passing as you told ] 

Mais il ne déclenche jamais l'abonnement dans le composant. Comment puis-je le tester efficacement ?

3voto

Wesley Trantham Points 621

Vous êtes tout près du but ! Quelques conseils pour vous aider :

  • ngOnInit s'exécute la toute première fois que vous appelez fixture.detectChanges (dans ce cas dans le beforeEach), il n'est donc pas nécessaire de l'appeler à nouveau dans votre test.
  • ActionsSubject hérite de BehaviorSubject, vous pouvez donc le traiter comme n'importe quel autre observable.
  • fixture.detectChanges met à jour le html dans votre test, puisque vous regardez directement une variable sur votre composant, il n'est pas nécessaire d'appeler
  • TestBed.get retours any il est utile de se présenter comme le service que l'on souhaite obtenir

    import { async, ComponentFixture, TestBed } from '@angular/core/testing';

    import { TestComponent } from './test.component'; import { ActionsSubject } from '@ngrx/store';

    describe('TestComponentComponent', () => { let component: TestComponent; let fixture: ComponentFixture<TestComponent>;

    beforeEach(async(() => { const actionSub: ActionsSubject = new ActionsSubject();

    TestBed.configureTestingModule({
      declarations: [TestComponent],
      providers: [{ provide: ActionsSubject, useValue: actionSub }],
    })
      .compileComponents();

    }));

    beforeEach(() => { fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; fixture.detectChanges(); });

    it('should create', () => { expect(component).toBeTruthy(); });

    fit('isUpdated should be true, when update action dispatched', () => { const actionSubject = TestBed.get(ActionsSubject) as ActionsSubject; const action = { type: 'Update' }; actionSubject.next(action);

    expect(component.isUpdated).toEqual(true);

    }); });

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