我试图测试一个简单的场景,定义了以下效果:
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
) { }
}
在这种情况下,我故意尝试在没有大理石的情况下实现这一点。也就是说,没有hot()
cold()
等等。我在网上找到的几个关于这个主题的例子只是使用了这些,但我现在正在寻找一种不使用这些的方法。
以下是到目前为止我在测试课上的成绩。TodosService
的模拟、快乐之路的第一次测试、模拟动作设置等都按预期进行。第二个测试,即我基本上试图确认EMPTY
可观测到的是由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测试文档在这里非常缺乏,因为它只发布了一些片段和边缘案例测试场景作为示例。
由于EMPTY
完成时没有发出next或错误,因此可以将其用作测试
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(...)