mercredi 11 juillet 2018

Test ngrx effect with service and marbles

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