Reactjs 如何使用Mocha进行单元测试,调用承诺重试的服务?
我的ReactJS项目中有一个调用通知服务的操作。如果服务调用失败一次,我必须在继续应用程序中的错误状态之前,仅尝试再次调用服务一次。为此,我使用了promise retry模块,并且能够在本地工作。然而,我现在正试图为Promisery包装的服务调用本身编写单元测试(Mocha),并且很难通过有意义的测试。首先,这里是调用服务的操作,包装在Promisery中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
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测试的,因为没有承诺在测试中链接。我不确定这里有什么好的策略,可能是模仿/spypromise重试
模块并从中链接一个承诺。感谢@estus的想法,我将试一试。estus说了什么,t通常,对于测试承诺,您会将承诺存根并强制其返回promise.resolve('mock data')