【发布时间】:2019-03-19 11:39:34
【问题描述】:
我正在尝试将一个测试函数写入一个 redux-observable 史诗。史诗在应用程序中运行良好,我可以检查它是否正确地消除了动作并在发射前等待 300 毫秒。但是由于某种原因,当我试图开玩笑地测试它时,去抖动运算符会立即触发。所以我确保去抖动工作的测试用例失败了。
这是测试用例
it('shall not invoke the movies service neither dispatch stuff if the we invoke before 300ms', done => {
const $action = ActionsObservable.of(moviesActions.loadMovies('rambo'));
loadMoviesEpic($action).subscribe(actual => {
throw new Error('Should not have been invoked');
});
setTimeout(() => {
expect(spy).toHaveBeenCalledTimes(0);
done();
}, 200);
});
这是我对间谍的定义。
jest.mock('services/moviesService');
const spy = jest.spyOn(moviesService, 'searchMovies');
beforeEach(() => {
moviesService.searchMovies.mockImplementation(keyword => {
return Promise.resolve(moviesResult);
});
spy.mockClear();
});
这就是史诗
import { Observable, interval } from 'rxjs';
import { combineEpics } from 'redux-observable';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounce';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/from';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/interval';
import 'rxjs/add/observable/concat';
import actionTypes from 'actions/actionTypes';
import * as moviesService from 'services/moviesService';
import * as moviesActions from 'actions/moviesActions';
const DEBOUNCE_INTERVAL_IN_MS = 300;
const MIN_MOVIES_SEARCH_LENGTH = 3;
export function loadMoviesEpic($action) {
return $action
.ofType(actionTypes.MOVIES.LOAD_MOVIES)
.debounce(() => Observable.interval(DEBOUNCE_INTERVAL_IN_MS))
.filter(({ payload }) => payload.length >= MIN_MOVIES_SEARCH_LENGTH)
.switchMap(({ payload }) => {
const loadingAction = Observable.of(moviesActions.loadingMovies());
const moviesResultAction = Observable.from(
moviesService.searchMovies(payload)
)
.map(moviesResultList => moviesActions.moviesLoaded(moviesResultList))
.catch(err => Observable.of(moviesActions.loadError(err)));
return Observable.concat(loadingAction, moviesResultAction);
});
}
const rootEpic = combineEpics(loadMoviesEpic);
export default rootEpic;
所以基本上这个东西不应该被调用,因为去抖动时间是 300 毫秒,我试图在 200 毫秒后检查间谍。但 10 毫秒后,间谍被调用。
如何正确测试这部史诗?我接受任何建议,但最好避免弹珠测试,只依赖计时器和假计时器。
谢谢:D
【问题讨论】:
-
几个月前我遇到了和你一模一样的问题,我终于用大理石图了^^stackoverflow.com/q/52832980/5692151
标签: rxjs jestjs redux-observable