首页 > 解决方案 > 如何使用 Mocha 对通过 promise-retry 调用服务进行单元测试?

问题描述

我的 ReactJS 项目中有一个调用通知服务的操作。要求,如果服务调用失败一次,我必须尝试再次调用服务一次,然后才能继续应用程序中的错误状态。我为此使用了 promise-retry 模块,并且能够让它在本地工作。但是,我现在正在尝试为 promiseRetry 包装的服务调用自己编写单元测试 (Mocha),并且很难通过有意义的测试。首先,这是调用服务的操作,包装在 promiseRetry 中。

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);
    });
});

这可以很好地测试初始尝试,但由于某种原因,即使我可以调试并逐步完成测试并点击 promiseRetry 中的所有代码,它们内部的操作(例如 dispatch(createNotificationSuccess()))是没有登录商店,所以我不能对它们运行期望语句。到目前为止,我尝试的每个角度都只从 store 中检索尝试,我无法从 Promise 的成功或失败方面获取任何数据。

我在 Stack Overflow 上找到了一些关于测试 promise-retry 本身的信息,但我需要知道,如果我对正在调用的服务存根并强制它失败,它将记录另一次尝试和另一次失败。或者,如果我对服务进行存根并强制它成功,它只会记录一次尝试、一次成功和完成。正如我之前提到的,我在商店中得到的唯一操作是尝试,与成功或失败无关,即使单步调试表明所有这些代码行都已命中。

这是我无法通过的测试示例:

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)),然后第二次(如果适用)?如果不是,它应该至少记录两次尝试。有什么建议吗?

标签: reactjsunit-testingreduxpromisemocha.js

解决方案


推荐阅读