Unit testing 如何在rxjs中对retryWhen操作符进行单元测试?
我正在尝试对一个自定义RxJS操作符进行单元测试。该操作符非常简单,它使用RetryWhen重试失败的HTTP请求,但有一个延迟,只有在HTTP错误在500范围内时才会重试。使用茉莉花,这是在一个角度的应用 我已经看过了: 不幸的是,更新SpyOn调用似乎不会改变连续重试时返回的可观测值。每次重试时,它都会使用原始spyon值重试 我还看了一些rxjs大理石的例子,它们似乎都不起作用。我不确定在这里是否可以使用rxjs大理石,因为(AFAIK)无法模拟这样一种情况:首先提交一个错误的观测值,然后在随后的尝试中提交一个成功的观测值 该代码基本上是以下代码的克隆:Unit testing 如何在rxjs中对retryWhen操作符进行单元测试?,unit-testing,rxjs,retrywhen,Unit Testing,Rxjs,Retrywhen,我正在尝试对一个自定义RxJS操作符进行单元测试。该操作符非常简单,它使用RetryWhen重试失败的HTTP请求,但有一个延迟,只有在HTTP错误在500范围内时才会重试。使用茉莉花,这是在一个角度的应用 我已经看过了: 不幸的是,更新SpyOn调用似乎不会改变连续重试时返回的可观测值。每次重试时,它都会使用原始spyon值重试 我还看了一些rxjs大理石的例子,它们似乎都不起作用。我不确定在这里是否可以使用rxjs大理石,因为(AFAIK)无法模拟这样一种情况:首先提交一个错误的观测值,然
导出函数delayedRetry(delayMS:number,maxRetry){
让retries=maxRetry;
回报率(src:可观察)=>
钢骨混凝土管(
retryWhen((错误:可观察)=>errors.pipe(
延迟(延迟毫秒),
合并映射(错误=>
(重试-->0&&error.status>=500)?(错误):抛出者错误(错误))
))
);
}
我希望能够证明它可以订阅一个在第一次尝试时返回错误,但随后返回成功响应的可观察对象。最终订阅应该显示可观测到的成功值
提前感谢您提供的任何见解。尝试使用此可观察对象作为源可观察对象进行测试
const source = (called,successAt)=>{
return defer(()=>{
if(called<successAt){
called++
return throwError({status:500})
}
else return of(true)
})
}
在前面的答案的基础上,我一直在使用这个,它可以让您更好地控制返回的内容
const source = (observables) => {
let count = 0;
return defer(() => {
return observables[count++];
});
};
然后可以这样使用
const obsA = source([
throwError({status: 500}),
of(1),
]);
或者可以与rxjs大理石一起使用,比如
const obsA = source([
cold('--#', null, { status: 500 }),
cold('--(a|)', { a: 1 }),
]);
要测试重试功能,您需要一个observable,它在每次调用时都会发出不同的事件。例如:
let alreadyCalled = false;
const spy = spyOn<any>(TestBed.inject(MyService), 'getObservable').and.returnValue(
new Observable((observer) => {
if (alreadyCalled) {
observer.next(message);
}
alreadyCalled = true;
observer.error('error message');
})
);
让alreadyCalled=false;
constspy=spyOn(TestBed.inject(MyService),'getObservable')。和.returnValue(
新可观察((观察者)=>{
如果(已调用){
观察员:下一个(信息);
}
alreadyCalled=true;
observer.error(“错误消息”);
})
);
此可观察对象将首先发出错误,然后发出下一个事件
您可以检查,如果您的可观察对象得到如下信息:
it('should retry on error', async(done) => {
let alreadyCalled = false;
const spy = spyOn<any>(TestBed.inject(MyDependencyService), 'getObservable').and.returnValue(
new Observable((observer) => {
if (alreadyCalled) {
observer.next(message);
}
alreadyCalled = true;
observer.error('error message');
})
);
const observer = {
next: (result) => {
expect(result.value).toBe(expectedResult);
done();
}
}
subscription = service.methodUnderTest(observer);
expect(spy).toHaveBeenCalledTimes(1);
}
it('should retry on error',async(done)=>{
设alreadyCalled=false;
const spy=spyOn(TestBed.inject(MyDependencyService)、'getObservable')和.returnValue(
新可观察((观察者)=>{
如果(已调用){
观察员:下一个(信息);
}
alreadyCalled=true;
observer.error(“错误消息”);
})
);
常量观察者={
下一步:(结果)=>{
expect(result.value).toBe(expectedResult);
完成();
}
}
订阅=service.methodUnderTest(观察者);
期望(间谍)。被催促的时间(1);
}
这帮了我的忙,我不知道你能用源代码做到这一点,很酷。
let alreadyCalled = false;
const spy = spyOn<any>(TestBed.inject(MyService), 'getObservable').and.returnValue(
new Observable((observer) => {
if (alreadyCalled) {
observer.next(message);
}
alreadyCalled = true;
observer.error('error message');
})
);
it('should retry on error', async(done) => {
let alreadyCalled = false;
const spy = spyOn<any>(TestBed.inject(MyDependencyService), 'getObservable').and.returnValue(
new Observable((observer) => {
if (alreadyCalled) {
observer.next(message);
}
alreadyCalled = true;
observer.error('error message');
})
);
const observer = {
next: (result) => {
expect(result.value).toBe(expectedResult);
done();
}
}
subscription = service.methodUnderTest(observer);
expect(spy).toHaveBeenCalledTimes(1);
}