У меня есть действие в моем проекте ReactJS, которое вызывает службу уведомлений. Требуется, чтобы в случае сбоя вызова службы я попытался повторно вызвать службу только один раз, прежде чем перейти к состоянию ошибки в приложении. Я использовал для этого модуль обещания повторов и смог заставить его работать локально. Однако сейчас я пытаюсь написать модульные тесты (Mocha) для самих вызовов службы в оберточном обещании и испытываю невероятные трудности с получением значимых тестов. Во-первых, вот действие, которое вызывает службу, заключенное в обещание возврата.
import promiseRetry from 'promise-retry';
...
const sendNotification = () => {
return (dispatch, getState) => {
const request = buildNotificationRequest(getState);
dispatch(createNotificationAttempt());
promiseRetry((retry) => {
return createNotificationService(request)
.catch(retry);
}, {retries: 1}).then(
() => {
dispatch(createNotificationSuccess());
},
(error) => {
dispatch(createNotificationError(error));
}
);
};
};
Обычно способ написания модульных тестов для действий, вызывающих службы, выглядит примерно так:
describe('notification actions', () => {
beforeEach(() => {
sendNotification = sinon.stub(services, 'createNotificationService').returns(Promise.resolve({}));
});
it('should log an attempt', () => {
store.dispatch(notificationActions.sendNotification());
const actions = store.getActions();
expect(actions[0].type).to.equal(notificationActions.ACTION_TYPES.CREATE_NOTIFICATION_ATTEMPT);
});
});
Это прекрасно работает для тестирования первоначальной попытки, но по какой-то причине, хотя я могу отлаживать и проходить тесты и выполнять весь код внутри обещания, действия внутри них (такие как диспетчеризация (createNotificationSuccess ()) )) не залогинены в магазине, поэтому я не могу на них запускать операторы ожидаемого. Каждый угол, который я пробовал до этого момента, извлекает только попытку из магазина, и я не могу получить какие-либо данные со стороны Обещания об успехе или неудаче.
Я нашел некоторую информацию о переполнении стека о тестировании самой повторной попытки обещания, но мне нужно знать, что, если я заглушу вызываемую службу и заставлю ее завершиться с ошибкой, она зарегистрирует еще одну попытку и другую ошибку. Или, если я заглушу службу и принудительно выполню ее, она зарегистрирует только одну попытку, одну успешную и завершенную. Как я уже упоминал ранее, единственное действие, которое я получаю в магазине, - это попытка, и ничего об успехе или неудаче, даже если выполнение отладки показывает, что все эти строки кода повреждены.
Вот пример теста, который я не могу пройти:
import * as services from 'services.js';
...
describe('the first time the service call fails', () => {
const error = {status: 404};
beforeEach(() => {
sendNotification = sinon.stub(services, 'createNotificationService').returns(Promise.reject(error));
});
it('should log a retry', () => {
store.dispatch(notificationActions.sendNotification());
const actions = store.getActions();
expect(actions[0].type).to.equal(notificationActions.ACTION_TYPES.CREATE_NOTIFICATION_ATTEMPT); // this passes
expect(actions[1].type).to.equal(notificationActions.ACTION_TYPES.CREATE_NOTIFICATION_FAILURE); // this fails because there are no other actions logged in the store.
Может быть, я неправильно понимаю, как работает обещание-повтор? Разве это не должно ударить по моему действию ошибки (dispatch (createNotificationError (error)) при первом сбое и во второй раз (если применимо)? Если нет, то это должно быть как минимум регистрация двух попыток. Любой совет?