Reputation: 374
Hi I am new to NGRX and am trying to write tests for the effects I have created, however it looks like the effect function is never actually running.
The effect I am trying to test is:
compelteAuthentication$ = createEffect(() => this.actions$.pipe(
ofType(fromActions.completeAuthentication),
switchMap(() => from(this.authService.completeAuthentication()).pipe(
map(user => fromActions.authenticationSuccess({ value: user.state})),
catchError(err => of(fromActions.authenticationFailed(err)))
))
));
The current version of the test is as follows:
import { UserEffects } from './user.effects';
import { AuthService } from './../../core/services/auth.service';
import { ApiServiceMock, ApplicationInsightServiceMock, AppSettingsServiceMock, AuthServiceMock, RouterMock, UserServiceMock } from './../../../testing-utils/mocks/service-mocks';
import { TestBed } from '@angular/core/testing';
import { Action } from '@ngrx/store';
import { provideMockActions } from '@ngrx/effects/testing';
import { Observable } from 'rxjs';
import * as userActions from '../actions/user.actions';
import { cold, hot } from 'jasmine-marbles';
import { User } from 'oidc-client';
let actions$ = new Observable<Action>();
let completeAuthSpy: jasmine.Spy;
let userEffects: UserEffects;
beforeEach(() => {
completeAuthSpy = jasmine.createSpy();
TestBed.configureTestingModule({
providers: [
provideMockActions(() => actions$),
UserEffects,
AppSettingsServiceMock,
// AuthServiceMock,
ApiServiceMock,
UserServiceMock,
RouterMock,
ApplicationInsightServiceMock,
{
provide: AuthService,
usevalue: {
completeAuthentication: completeAuthSpy
}
}
],
});
userEffects = TestBed.inject(UserEffects);
});
describe('UserEffects', () => {
describe('CompleteAuthentication', () => {
it('Should call success action', () => {
const userState = new User({
id_token: 'TestID',
session_state: 'TestState',
access_token: 'TestToken',
refresh_token: 'TestRefreshToken',
token_type: 'TestTokenType',
scope: 'TestScope',
profile: {} as any,
expires_at: 6,
state: undefined,
});
const outcome = userActions.authenticationSuccess({ value: userState.state });
const response = cold('-a|', { a: userState });
const expected = cold('--b', { b: outcome });
completeAuthSpy.and.returnValue(response.toPromise());
actions$ = hot('-c', { c: userActions.completeAuthentication });
expect(userEffects.compelteAuthentication$).toBeObservable(expected);
expect(completeAuthSpy).toHaveBeenCalled();
});
});
});
so when the above test is ran the first expect fails and it returns []
instead of the action as expected.
Any clue what I am missing here?
Upvotes: 0
Views: 738
Reputation: 12196
rxjs observables are lazy. That means that code executes on subscribtion. in your test expect(userEffects.compelteAuthentication$).toBeObservable(expected);
is making a subscribtion. so just swap order of expect
s and everything will be fine
actions$ = hot('-c', { c: userActions.completeAuthentication });
expect(userEffects.compelteAuthentication$).toBeObservable(expected);
expect(completeAuthSpy).toHaveBeenCalled();
Upvotes: 1