NGXS: How to test if an action was dispatched?

前端 未结 3 2185
遇见更好的自我
遇见更好的自我 2021-02-14 06:57

How to unit test whether an action was dispatched?

For example, in a LogoutService, I have this simple method:

  logout(username: string) {
    store.dis         


        
3条回答
  •  栀梦
    栀梦 (楼主)
    2021-02-14 07:13

    NGXS Pipeable Operators

    Actions in NGXS are handled with Observables. NGXS provides you Pipeable Operators, for your test you could use the ofActionDispatched. Here is the list I have taken from the NGXS documentation:

    • ofAction triggers when any of the below lifecycle events happen
    • ofActionDispatched triggers when an action has been dispatched
    • ofActionSuccessful triggers when an action has been completed successfully
    • ofActionCanceled triggers when an action has been canceled
    • ofActionErrored triggers when an action has caused an error to be thrown
    • ofActionCompleted triggers when an action has been completed whether it was successful or not (returns completion summary)

    Answer

    1. Create variable actions$

    describe('control-center.state', () => {
      let actions$: Observable;
    
      // ...
    });
    

    2. Initialize variable actions$ with observable

    beforeEach(() => {
      TestBed.configureTestingModule({
        imports: [
          NgxsModule.forRoot([AppState]),
          NgxsModule.forFeature([ControlCenterState])
        ]
      });
      store = TestBed.get(Store);
      actions$ = TestBed.get(Actions);
    })
    

    3.1 Test if 1 action has been called:

    Filter your actions from the stream with the operator ofActionsDispatched().

    it('should dispatch LogoutAction', (done) => {
      actions$.pipe(ofActionDispatched(LogoutAction)).subscribe((_) => {
        done();
      });
    
      service.logout();
    });
    

    3.2 Test if multiple actions have been called:

    Use the RXJS zip operator to combine the two observables with the ofActionsDispatched() function (zip: after all observables emit, emit values as an array).

    it('should dispatch ResetStateAction and LogoutAction', (done) => {
      zip(
        actions$.pipe(ofActionDispatched(ResetStateAction)),
        actions$.pipe(ofActionDispatched(LogoutAction))
      ).subscribe((_) => {
        done();
      });
    
      service.logout();
    });
    

    The spec will not complete until its done is called. If done is not called a timeout exception will be thrown.

    From the Jasmine documentation.

提交回复
热议问题