如何测试RxJs脱口而出的史诗?

如何测试RxJs脱口而出的史诗?,rxjs,jestjs,redux-observable,Rxjs,Jestjs,Redux Observable,我正试图为一个redux可观测史诗编写一个测试函数。epic在应用程序中运行良好,我可以检查它是否正确地解除了动作的抖动,并在发出之前等待300毫秒。但由于某种原因,当我试图用jest测试它时,debounce操作符会立即触发。因此,我的测试用例无法确保去盎司工作 这是测试用例 it('如果我们在300ms之前调用,则不应调用电影服务,也不发送内容',完成=>{ const$action=ActionsObservable.of(moviesActions.loadMovies('rambo')

我正试图为一个redux可观测史诗编写一个测试函数。epic在应用程序中运行良好,我可以检查它是否正确地解除了动作的抖动,并在发出之前等待300毫秒。但由于某种原因,当我试图用jest测试它时,debounce操作符会立即触发。因此,我的测试用例无法确保去盎司工作

这是测试用例

it('如果我们在300ms之前调用,则不应调用电影服务,也不发送内容',完成=>{
const$action=ActionsObservable.of(moviesActions.loadMovies('rambo'));
loadMoviesEpic($action).订阅(实际=>{
抛出新错误('不应被调用');
});
设置超时(()=>{
预期(间谍)。已被催收时间(0);
完成();
}, 200);
});
这是我对间谍的定义

jest.mock('services/moviesService');
const spy=jest.spyOn(moviesService,'searchMovies');
在每个之前(()=>{
moviesService.searchMovies.mockImplementation(关键字=>{
返回承诺。解决(moviesResult);
});
spy.mockClear();
});
这就是史诗

import{Observable,interval}来自'rxjs';
从'redux observable'导入{combinepics};
导入'rxjs/add/operator/switchMap';
导入'rxjs/add/operator/map';
导入“rxjs/add/operator/debounce”;
导入'rxjs/add/operator/filter';
导入“rxjs/add/operator/catch”;
导入“rxjs/add/observable/from”;
导入“rxjs/add/observable/of”;
导入“rxjs/add/observable/interval”;
导入“rxjs/add/observable/concat”;
从“动作/动作类型”导入动作类型;
从“服务/电影服务”导入*作为电影服务;
从“actions/moviesActions”导入*作为moviesActions;
常数去盎司间隔(单位:毫秒)=300;
const MIN_MOVIES_SEARCH_LENGTH=3;
导出函数loadMoviesEpic($action){
返回$action
.of类型(ActionType.MOVIES.LOAD_MOVIES)
.debounce(()=>可观察的间隔(debounce\u interval\u IN\u MS))
.filter(({payload})=>payload.length>=MIN\u MOVIES\u SEARCH\u length)
.switchMap({payload})=>{
const loadingAction=可观察的(moviesActions.loadingMovies());
const moviesResultAction=可观察的(
moviesService.searchMovies(有效负载)
)
.map(moviesResultList=>moviesActions.moviesLoaded(moviesResultList))
.catch(err=>Observable.of(moviesActions.loadError(err));
返回可观察的。concat(加载操作、移动结果);
});
}
const rootEpic=combineEpics(loadMoviesEpic);
导出默认rootEpic;
所以基本上这个东西不应该被称为,因为去盎司时间是300毫秒,我试图在200毫秒后检查间谍。但10毫秒后,间谍被调用

如何正确测试这部史诗?我接受任何建议,但最好避免大理石测试,只依赖计时器和假计时器。


谢谢:D

而不是setTimeout try

问题是
去抖动
去抖动时间
在到达可观测值末尾时立即发出

因此,由于您使用的发射,因此到达可观测值的末端,
debounce
允许立即通过最后发射的值

下面是一个简单的测试,演示了该行为:

从'rxjs'导入{of};
从“rxjs/operators”导入{debounceTime};
测试('of',()=>{
const spy=jest.fn();
of(1,2,3)
.管道(去BounceTime(1000000))
.订阅(v=>spy(v));
expect(spy).toHaveBeenCalledWith(3);//立即发出3
})

要有效地测试
debounce
debounceTime
,您需要使用一个持续发射且不会以
interval
结束的可观察对象:

从'rxjs'导入{interval};
从“rxjs/operators”导入{debounceTime};
测试('interval',done=>{
const spy=jest.fn();
间隔(100)
.管道(去BounceTime(500))
.订阅(v=>spy(v));
设置超时(()=>{
期待(间谍).not.tohavebeencall();//成功!
完成();
}, 1000);
});

这里的主要问题是,去盎司功能会立即触发,而不是等待300毫秒,因此advanceTimersByTime在这里并不真正适用,因为我不想提前时间。但是试着去理解为什么在我的测试中会立即触发去盎司。哦,我明白了,在问题中,你好像说setTimeout是在10毫秒后调用的。几个月前,我和你的问题完全一样,我最终使用了marble图^^