NgRx Effects 单元测试:测试 catchError 案例,没有弹珠
NgRx Effects Unit Testing: Test catchError Case, Without Marbles
我正在尝试测试一个简单的场景,定义了以下效果:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { TodosService } from '../services/todos.service';
import { getTodos, getTodosSuccess } from './todos.actions';
@Injectable()
export class TodosEffects {
loadTodos$ = createEffect(() =>
this.actions$.pipe(
ofType(getTodos),
mergeMap(() => this.todosService.getTodos()
.pipe(
map(todos => getTodosSuccess({ todoItems: todos })),
catchError(() => EMPTY)
)
)
)
);
constructor(
private actions$: Actions,
private todosService: TodosService
) { }
}
在这种情况下,我故意尝试在没有 Marbles 的情况下使它正常工作。也就是说,没有 hot()
cold()
等等。我在网上找到的几个关于这个主题的例子只是使用了那些,但我现在正在寻找一种方法来做到这一点。
这是我目前的测试 class。 TodosService
的模拟、快乐路径的首次测试、模拟操作设置等都按预期工作。第二个测试,我基本上是在尝试确认 EMPTY
observable 是由 catchError
生成的,这是我正在努力的地方:
import { TestBed } from '@angular/core/testing';
import { TodosService } from '@app/services/todos.service';
import { provideMockActions } from '@ngrx/effects/testing';
import { Action } from '@ngrx/store';
import { EMPTY, Observable, of } from 'rxjs';
import { TodoItem } from './todo-model';
import { getTodos, getTodosSuccess } from './todos.actions';
import { TodosEffects } from './todos.effects';
let actions$ = new Observable<Action>();
let effects: TodosEffects;
let todosServiceSpy: jasmine.SpyObj<TodosService>;
describe('Todos Effects', () => {
beforeEach(() => {
const todosServiceSpyObject = jasmine.createSpyObj('TodosService', ['getTodos']);
TestBed.configureTestingModule({
providers: [
TodosEffects,
provideMockActions(() => actions$),
{ provide: TodosService, useValue: todosServiceSpyObject }
]
});
effects = TestBed.inject(TodosEffects);
todosServiceSpy = TestBed.inject<TodosService>(TodosService) as jasmine.SpyObj<TodosService>;
});
it('should return successful todo get action with service results', () => {
actions$ = of(getTodos());
const expectedTodos: TodoItem[] = [{} as TodoItem];
todosServiceSpy.getTodos.and.returnValue(of(expectedTodos));
const expectedAction = getTodosSuccess({ todoItems: expectedTodos });
effects.loadTodos$.subscribe(result => {
expect(result).toEqual(expectedAction);
});
});
it('should return EMPTY observable I think?', () => {
actions$ = of(getTodos());
// todosServiceSpy.getTodos.and.throwError('');
todosServiceSpy.getTodos.and.returnValue(throwError(''));
const expected = EMPTY;
effects.loadTodos$.subscribe();
// TODO: What to expect / etc. here?
});
});
NgRx Effects testing documentation is unfortunately quite lacking here,因为它仅发布示例的片段和边缘案例测试场景。
由于 EMPTY
完成时没有发出下一个或错误,您可以将其用作测试
let nextCount = 0
let errorCount = 0
let completeCount = 0
effects.loadTodos$.subscribe(
() => {nextCount++},
() => {errorCount++}
() => {completeCount++}
)
// test that only completeCount === 1, and others are 0
expect(....).toEqual(...)
我正在尝试测试一个简单的场景,定义了以下效果:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { TodosService } from '../services/todos.service';
import { getTodos, getTodosSuccess } from './todos.actions';
@Injectable()
export class TodosEffects {
loadTodos$ = createEffect(() =>
this.actions$.pipe(
ofType(getTodos),
mergeMap(() => this.todosService.getTodos()
.pipe(
map(todos => getTodosSuccess({ todoItems: todos })),
catchError(() => EMPTY)
)
)
)
);
constructor(
private actions$: Actions,
private todosService: TodosService
) { }
}
在这种情况下,我故意尝试在没有 Marbles 的情况下使它正常工作。也就是说,没有 hot()
cold()
等等。我在网上找到的几个关于这个主题的例子只是使用了那些,但我现在正在寻找一种方法来做到这一点。
这是我目前的测试 class。 TodosService
的模拟、快乐路径的首次测试、模拟操作设置等都按预期工作。第二个测试,我基本上是在尝试确认 EMPTY
observable 是由 catchError
生成的,这是我正在努力的地方:
import { TestBed } from '@angular/core/testing';
import { TodosService } from '@app/services/todos.service';
import { provideMockActions } from '@ngrx/effects/testing';
import { Action } from '@ngrx/store';
import { EMPTY, Observable, of } from 'rxjs';
import { TodoItem } from './todo-model';
import { getTodos, getTodosSuccess } from './todos.actions';
import { TodosEffects } from './todos.effects';
let actions$ = new Observable<Action>();
let effects: TodosEffects;
let todosServiceSpy: jasmine.SpyObj<TodosService>;
describe('Todos Effects', () => {
beforeEach(() => {
const todosServiceSpyObject = jasmine.createSpyObj('TodosService', ['getTodos']);
TestBed.configureTestingModule({
providers: [
TodosEffects,
provideMockActions(() => actions$),
{ provide: TodosService, useValue: todosServiceSpyObject }
]
});
effects = TestBed.inject(TodosEffects);
todosServiceSpy = TestBed.inject<TodosService>(TodosService) as jasmine.SpyObj<TodosService>;
});
it('should return successful todo get action with service results', () => {
actions$ = of(getTodos());
const expectedTodos: TodoItem[] = [{} as TodoItem];
todosServiceSpy.getTodos.and.returnValue(of(expectedTodos));
const expectedAction = getTodosSuccess({ todoItems: expectedTodos });
effects.loadTodos$.subscribe(result => {
expect(result).toEqual(expectedAction);
});
});
it('should return EMPTY observable I think?', () => {
actions$ = of(getTodos());
// todosServiceSpy.getTodos.and.throwError('');
todosServiceSpy.getTodos.and.returnValue(throwError(''));
const expected = EMPTY;
effects.loadTodos$.subscribe();
// TODO: What to expect / etc. here?
});
});
NgRx Effects testing documentation is unfortunately quite lacking here,因为它仅发布示例的片段和边缘案例测试场景。
由于 EMPTY
完成时没有发出下一个或错误,您可以将其用作测试
let nextCount = 0
let errorCount = 0
let completeCount = 0
effects.loadTodos$.subscribe(
() => {nextCount++},
() => {errorCount++}
() => {completeCount++}
)
// test that only completeCount === 1, and others are 0
expect(....).toEqual(...)