Hi I'm trying to test my ngrx effects services, but getting some errors
I'm very new to the concept of marbles, but I did read in StackOverflow comments here that this might be a bug
So, wondering if it's worth me moving in this direction or does someone have any pointers/tutorials, I have looked at a few already,
but they're either outdated, using testrunner, or not very clear
My effect:
import { Injectable } from '@angular/core';
import {Actions, Effect, ofType} from "@ngrx/effects";
import { mergeMap, map, catchError, tap } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { AuthService } from '../../../services/auth.service';
import { LogIn, LOGIN, LogInSuccess, LOGIN_FAILURE, LogInFailure, LOGIN_SUCCESS } from '../actions/login.actions';
import { Router } from '@angular/router';
import * as jwt_decode from 'jwt-decode';
import * as loginReducer from '../reducers/login.reducers'
@Injectable()
export class LoginEffects {
constructor(private actions$: Actions,
private authService: AuthService,
private router: Router) {}
@Effect() login$: Observable<any> = this.actions$
.pipe(
ofType<LogIn>(LOGIN),
mergeMap(action => {
return this.authService.login(action.payload.email, action.payload.password)
.pipe(
map((data)=> {
//Decode the returned jwt
let decodedData = jwt_decode(data.token)
let userState:loginReducer.State = {
isAuthenticated: true,
token:data.token,
name:decodedData.name
}
return new LogInSuccess(userState)
}),
catchError((error) => {
return Observable.of(new LogInFailure({ error: error }));
})
)
}),
)
// .
@Effect({dispatch:false}) logInSuccess$: Observable<any> = this.actions$
.pipe(
ofType<LogInSuccess>(LOGIN_SUCCESS),
tap((user) => {
localStorage.setItem('token', user.token);
localStorage.setItem('name', user.name);
localStorage.setItem('isAuthenticated', user.isAuthenticated);
// this.router.navigateByUrl('/');
})
)
effects.spec.ts
import { LoginEffects } from "./login.effects";
import {toArray} from 'rxjs/operator/toArray';
import {toPromise} from 'rxjs/operator/toPromise';
import { hot, cold } from 'jasmine-marbles';
import { Observable } from "rxjs";
import { Actions } from "@ngrx/effects";
describe('LoginEffects', () => {
const router = jasmine.createSpyObj('Router', ['navigate'])
it('should be created', () => {
const actions = new Actions(hot('-a-|', {a: {type: 'LOGIN'}}));
let expected = {
isAuthenticated: true,
token:'token',
name:'Roy Adams'
}
const service = stubService(expected);
const effects = new LoginEffects(actions, service, router);
expect(effects.login$).toBeTruthy();
});
it('should work with effects that only use observables', () => {
const actions = new Actions(hot('a', {a: {type: 'LOGIN'}}));
let expected = {
isAuthenticated: true,
token:'token',
name:'Roy Adams'
}
const service = stubService(expected);
const effects = new LoginEffects(actions, service, router);
expect(effects.login$).toBeObservable(hot('a', {a: {type: 'LOGIN_SUCCESS', payload: expected}}));
});
function stubService(response: any): any {
const service = jasmine.createSpyObj('service', [ 'getDummyData' ]);
const isError = response instanceof Error;
const serviceResponse = isError ? Observable.throw(response) : Observable.of(response);
service.getDummyData.and.returnValue(serviceResponse);
return service;
}
});
// extract into utils file
export function readAll<T>(o: Observable<T>): Promise<T[]> {
return toPromise.call(toArray.call(o));
}
The error I'm getting for the "should work with effects that only use observables":
Expected $.length = 0 to equal 1.
Expected $[0] = undefined to equal Object({ frame: 0, notification: Notification({ kind: 'N', value: Object({ type: 'LOGIN_SUCCESS', payload: Object({ isAuthenticated: true, token: 'token', name: 'Roy Adams' }) }), error: undefined, hasValue: true }) })
Aucun commentaire:
Enregistrer un commentaire