Повторная проверка мрамора
У меня есть SocketService. Этот класс отвечает за сокетное соединение и обмен сообщениями с сервером. Я написал некоторый код, чтобы мой клиент мог восстановить соединение при потере соединения. Он должен сделать 3 попытки с 5-секундной задержкой между ними и в случае неудачи перенаправить на страницу входа.
После этого я написал тест, но не могу заставить его работать даже близко к тому, что происходит.
Я пытаюсь смоделировать 2 ошибки на send
и одно успешное сообщение. Что должно привести к 3 попыткам переподключения и последней успешной.
Вот мой тест https://stackblitz.com/edit/jasmine-marbles-testing-jdvcnm?file=src/test.spec.ts
Я ожидаю, что мраморная диаграмма будет что-то рядом -# 5s # 5s (a|)
(в тесте есть другая диаграмма, так как я пробовал разные).
1 ответ
Почему ты не используешь retry
для этого. Это именно то, что вы пытались сделать с retryWhen
,
describe('marble', () => {
let service: SocketService;
beforeEach(() => service = new SocketService());
it('should make 3 attemps and reconnect on 3rd', () => {
const values = {
a: {
status: 200
}
};
const expected = '3500ms a';
(service as any).socket = {};
spyOn(localStorage, 'getItem').and.returnValue('hello');
testScheduler.run(({ cold, expectObservable }) => {
const source$ = createRetryableStream(
cold('1s #'),
cold('2s #'),
cold('500ms a', values)
).pipe(
retry(2)
);
// trigger close socket event to make listener work
service.onClose.next();
expectObservable(source$).toBe(expected, values);
});
});
});
Кроме этого, ожидание более одного терминального события не было правильным. У вас может быть только одно конечное событие (либо ошибка, либо завершение), самое большее (это означает, что вам не нужно его иметь).
Если ошибка возникает в некоторой внутренней наблюдаемой и обрабатывается внутренним оператором, она не будет видна снаружи. Таким образом, ожидаемые значения не могут быть как -# 5s # 5s (a|)
, На основании трех cold
наблюдаемые, которые были созданы (с мрамором '1s #'
, '2s #'
а также '500ms a'
), ожидаемый результат будет '3500ms a'
(ожидание 1s
+ 2s
+ 500ms
затем испуская a
).
Так как исходный источник не имеет терминального события (последнее, на которое вы нацеливались, чтобы переподписаться retry
), вы не можете иметь конечное событие в ожидаемых мраморах вообще. Если вам нужно терминальное событие, используйте это 500ms a|
в третьем cold
наблюдаемый и '3500ms a|'
как expected
,