Reactjs 如何使用Mocha进行单元测试,调用承诺重试的服务?

Reactjs 如何使用Mocha进行单元测试,调用承诺重试的服务?,reactjs,unit-testing,redux,promise,mocha.js,Reactjs,Unit Testing,Redux,Promise,Mocha.js,我的ReactJS项目中有一个调用通知服务的操作。如果服务调用失败一次,我必须在继续应用程序中的错误状态之前,仅尝试再次调用服务一次。为此,我使用了promise retry模块,并且能够在本地工作。然而,我现在正试图为Promisery包装的服务调用本身编写单元测试(Mocha),并且很难通过有意义的测试。首先,这里是调用服务的操作,包装在Promisery中 import promiseRetry from 'promise-retry'; ... const sendNotificat

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

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);
    });
});
这对于测试初始尝试很有效,但由于某些原因,即使我可以调试和逐步完成测试并点击Promisery中的所有代码,其中的操作(如dispatch(createNotificationSuccess())没有记录在存储中,因此我无法对其运行expect语句。到目前为止,我尝试的每个角度都只从存储中检索尝试,我无法从承诺的成功或失败方面获得任何数据

我已经找到了一些关于测试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))吗?如果没有,它应该至少记录两次尝试。有什么建议吗?

代码不完整。没有createNotificationService,不清楚它来自哪里,什么是
服务
,以及为什么
sinon.stub(服务,'createNotificationService'))
应该可以工作。我更新了伪代码。createNotificationService存在于services.js中。它是一个简单的axios.get()调用。测试的代码是异步的,而测试是同步的。这个问题是特定于Redux测试的,因为没有承诺在测试中链接。我不确定这里有什么好的策略,可能是模仿/spy
promise重试
模块并从中链接一个承诺。感谢@estus的想法,我将试一试。estus说了什么,t通常,对于测试承诺,您会将承诺存根并强制其返回
promise.resolve('mock data')