Как выполнить модульное тестирование вызова службы с повторной попыткой обещания с использованием Mocha? - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть действие в моем проекте 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)) при первом сбое и во второй раз (если применимо)? Если нет, то это должно быть как минимум регистрация двух попыток. Любой совет?

...