如何在ngrx中测试效果?

时间:2018-04-25 10:48:51

标签: redux ngrx effects side-effects ngrx-effects

我只想在下面获取我的getUser效果。

我正在使用angular5,typescript和ngrx。

我愿意接受下面的例子。

这是我的效果:

import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/catch';
import { Effect, Actions } from '@ngrx/effects';
import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map, switchMap } from 'rxjs/operators';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

import * as fromUser from '../actions/user-state.actions';
import { UserService } from '../services/user-state.service';
import { UserStateState } from '../models/user-state.interfaces';

@Injectable()
export class UserStateEffects {

  @Effect({ dispatch: true })
  getUser$: Observable<any> = this.actions$
    .ofType(fromUser.GET_USER)
    .pipe(
      switchMap(() => this.userService.getUser()),
      map((result: any) => new fromUser.UserSuccess(result)))
    .catch((error: HttpErrorResponse) => of(new fromUser.UserFailure(error)));

  constructor(
    private actions$: Actions,
    private userService: UserService
  ) {}
}

这是效果测试的规格:

import 'rxjs/add/observable/throw';
import { Actions } from '@ngrx/effects';
import { cold, hot } from 'jasmine-marbles';
import { empty } from 'rxjs/observable/empty';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { TestBed } from '@angular/core/testing';

import * as actions from '../actions/user-state.actions';
import { UserService } from '@tradingapplication/user-state/src/state/services/user-state.service';
import { UserStateEffects } from '@tradingapplication/user-state/src/state/effects/user-state.effects';
import { UserStateState } from '../models/user-state.interfaces';
import { UserStateConstants } from '../../user-state.constants';

export class TestActions extends Actions {
  constructor(){
    super(empty());
  }
  set stream(source: Observable<any>){
    this.source = source
  }
}

export function getActions() {
  return new TestActions();
}

fdescribe('UserStateEffects', function () {
  let actions$: TestActions;
  let service: UserService;
  let effects: UserStateEffects;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule ],
      providers: [
        UserService,
        UserStateConstants,
        UserStateEffects,
        { provide: Actions, useFactory: getActions },
      ],
    });

    actions$ = TestBed.get(Actions);
    service = TestBed.get(UserService);
    effects = TestBed.get(UserStateEffects);

    spyOn(service, 'getUser').and.returnValue(of(null));
  });

  it('should return user from GetUser', () => {
    const action = actions.GET_USER;
    const completion = new actions.UserSuccess({});

    actions$.stream = hot('-a', { a: action });
    const expected = cold('-b', { b: completion });

    expect(effects.getUser$).toBeObservable(expected);
  });
});

1 个答案:

答案 0 :(得分:0)

您可能需要查看NGRX / Google小组的NGRX example app。它利用Jasmine-Marbles测试流,如NGRX Effects中所使用的那样。这样,您可以在执行后测试流是否关闭,以及在预期值到达之前通过它们传递了多少元素。所有这一切只有几个破折号(滴答声)。