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<any>;
// ...
});
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.