看起来你颠倒mergeMap()
了retryWhen()
. timer(100)
如果尝试少于 3 次,您应该返回,如下所示:
describe('marble', () => {
let service: SocketService;
beforeEach(() => service = new SocketService());
it('should make 3 attempts and reconnect on 3rd', () => {
const values = {
a: {
status: 200
}
};
const expected = '203ms a';
(service as any).socket = {};
spyOn(localStorage, 'getItem').and.returnValue('hello');
testScheduler.run(({ cold, expectObservable }) => {
const source$ = createRetryableStream(
cold('-#'),
cold('-#'),
cold('-a', values)
).pipe(
retryWhen(errors => errors.pipe(
mergeMap((err, i) => {
return 3 > i
? timer(100, testScheduler)
: throwError(err);
})
))
);
// trigger close socket event to make listener work
service.onClose.next();
expectObservable(source$).toBe(expected, values);
});
});
});
除此之外,期望不止一个终端事件是不正确的。您最多只能有一个终端事件(错误或完成)(这意味着您不必有任何)。
如果某个内部 observable 发生错误并由内部运算符处理,则从外部看不到它。所以,期望值不能像-# 5s # 5s (a|)
. 基于弹珠'-#'
,'-#'
并'-a'
提供给cold
可观察对象,预期输出将是'203ms a'
(等待 3 次 1 毫秒 3 个-
标志 + 两个timer
s 等待 100 毫秒两个错误,然后发出a
)。
由于源 observable 没有终端事件(最后一个,您打算重新订阅retryWhen
),因此您根本无法在预期的弹珠中出现终端事件。如果您需要终端事件,请-a|
在第三个cold
observable 和'203ms a|'
as中使用它expected
。