Search code examples
angularrxjsjestjsngxs

How to unit test if an action has been dispatched in another action?


I'd like, as the title says, to test that my action dispatches another action when the observable returns.

Here is my code :

@Action(FetchRoles)
fetchRoles(ctx: StateContext<RoleStateModel>, action: FetchRoles) {
  return this.rolesGateway.fetchRoles()
    .pipe(
      tap(roles => ctx.patchState({ roles })),
    );
}

@Action(UpdateMyRole)
updateMyRole(ctx: StateContext<RoleStateModel>, action: UpdateMyRole) {
  return this.rolesGateway.updateMyRole(action.roleToUpdate)
    .pipe(
      tap(() => {
        ctx.dispatch(new FetchRoles()); // <-- WHAT I WANT TO SPY AND TEST
        this.feedbackManagerService.success('Role updated');
      }),
    );
}

I've tried to test it synchronously, like this

store.dispatch(new UpdateApplicationRole(applicationCode, roleManage));

expect(gateway.updateMyRole).toHaveBeenCalledTimes(1);
expect(gateway.updateMyRole).toHaveBeenCalledWith(roleToUpdate);
expect(gateway.fetchRoles).toHaveBeenCalledTimes(1);
expect(gateway.fetchRoles).toHaveBeenCalledWith();
expect(feedbackManagerService.success).toHaveBeenCalledTimes(1);
expect(feedbackManagerService.success).toHaveBeenCalledWith('Role updated');

But also with fakeAsync ... tick(100)

store.dispatch(new UpdateApplicationRole(applicationCode, roleManage));
tick(100)
...

Or even an async ... await

await store.dispatch(new UpdateApplicationRole(applicationCode, roleManage));
...

But everytime, I receive only calls in the gateway.updateMyRole, not the 4 after. Initially, I wanted to test only the ctx.dispatch(new FetchRoles())

Thanks for the help


Solution

  • I was overthinking. I just needed to mock my gateway observables with a value : of() => of(null)