我有一个SocketService。此类负责套接字连接和与服务器的消息传递。我编写了一些代码,以使客户端能够在连接断开时重新连接。它应该进行3次尝试,两次尝试之间要间隔5秒,如果没有成功,则会重定向到登录页面。
在那之后,我编写了一个测试,但是我无法使其工作甚至接近发生的事情。
我正在尝试模拟send
上的2个错误和一条成功的消息。什么会导致3次重新连接尝试和最后一次成功的连接。
这是我的考试https://stackblitz.com/edit/jasmine-marbles-testing-jdvcnm?file=src/test.spec.ts
我希望大理石图在-# 5s # 5s (a|)
附近(在测试中,由于我尝试了不同的图,所以还有另一张图)。
答案 0 :(得分:0)
似乎您颠倒了mergeMap()
中使用的retryWhen()
运算符的逻辑。如果尝试次数少于3次,则应返回timer(100)
,如下所示:
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);
});
});
});
除此之外,期望多个终端事件是不正确的。最多只能有一个终端事件(错误或完成)(这意味着您不必有任何事件)。
如果某个内部可观察到的错误发生并由内部运算符处理,则从外部看不到该错误。因此,期望值不能像-# 5s # 5s (a|)
。根据提供给'-#'
观测值的大理石'-#'
,'-a'
和cold
,预期输出将为'203ms a'
(3 { 1}}符号+两个-
,等待100 ms的两个错误,然后发出timer
)。
由于可观察的源没有终端事件(最后一个目标是您打算用a
重新订阅),因此根本无法在预期的弹珠中发生终端事件。如果您需要结束事件,请在可观察到的第三个retryWhen
中使用此-a|
,并将cold
用作'203ms a|'
。