我在单元测试 ngrx 效果上有奇怪的错误,这是我的例子
export const noop = (): any => null;
export const obsNoop = () => of({});
export const mockObs = () => {
return {
subscribe: () => { }
};
};
const initialState: Tutorial[] = [
{ id: 1, name: 'Google', url: 'google.com' },
{ id: 2, name: 'Yahoo', url: 'yahoo.com' },
];
class MockTutorialsService {
getAll = obsNoop;
}
fdescribe('AppEffects', () => {
let actions$: Observable<any>;
let effects: TutorialEffects;
let store: MockStore<AppState>;
let httpService: TutorialsService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
TutorialEffects,
provideMockActions(() => actions$),
provideMockStore({ initialState }),
{ provide: TutorialsService, useClass: MockTutorialsService }
],
});
effects = TestBed.inject(TutorialEffects);
store = TestBed.inject(MockStore);
httpService = TestBed.inject(TutorialsService);
});
it('should be created', () => {
expect(effects).toBeTruthy();
});
// Testing API interaction
describe('onFetchUsers$', () => {
it('should fire if users is null', (done) => {
const spy = spyOn(httpService, 'getAll').and.callThrough();
actions$ = of(TutorialActions.GET_TUTORIALS);
effects.loadTutorials$.subscribe((res) => {
expect(res).toEqual(new TutorialActions.SuccesGetTutorials(res));
expect(spy).toHaveBeenCalledTimes(1);
done();
});
});
});
});
我得到的错误与 karma likeError 有关: 超时 - 异步功能未在 5000 毫秒内完成(由 jasmine.DEFAULT_TIMEOUT_INTERVAL 设置)
有人知道我哪里出错了吗?
效果图
Injectable()
export class TutorialEffects {
loadTutorials$ = createEffect(() =>
this.action$.pipe(
ofType(TutorialActions.GET_TUTORIALS),
switchMap(() =>
this.tutorialService.getAll().pipe(
map((tutorial: Tutorial[]) => new TutorialActions.SuccesGetTutorials(tutorial)),
catchError((error) => of(error))
)
)
)
);
constructor(private action$: Actions, private tutorialService: TutorialsService) { }
}
答案 0 :(得分:0)
没有看到效果,我只是猜测,但问题是测试没有进入 effects.loadTutorials$.subscribe
行内并在 done
内调用 5 seconds
。
effects.loadTutorials$.subscribe((res) => {
console.log('!! Inside of the subscribe !!'); // make sure you see this log
expect(res).toEqual(new TutorialActions.SuccesGetTutorials(res));
expect(spy).toHaveBeenCalledTimes(1);
done();
});
我认为罪魁祸首是 and.callThrough()
。我认为你应该返回一个虚假的回复。
const spy = spyOn(httpService, 'getAll').and.returnValue(of({/* mock response */ });
====== 编辑 ======
loadTutorials$ = createEffect(() =>
this.action$.pipe(
ofType(TutorialActions.GET_TUTORIALS),
switchMap(() => {
console.log('!! Inside of switchMap !!');
return this.tutorialService.getAll().pipe(
map((tutorial: Tutorial[]) => {
console.log('!! Inside of map !!');
return new TutorialActions.SuccesGetTutorials(tutorial); }),
catchError((error) => of(error))
)
})
)
);