如何测试redux-thunk中间件异步函数?

时间:2016-01-18 18:15:23

标签: mocha sinon redux chai redux-thunk

我正在尝试使用 mocha,chai和sinon 测试我的asyn thunk中间件功能(我的第一次!)。

请考虑我的档案:

ayncActionCreators.js

export const fetchCurrentUser = () => {
   return (dispatch) => {
      setTimeout(dispatch, 100);
   }
};

ayncActionCreators.spec.js

//...
it('Should work', () => {
   const dispatch = sinon.spy();
   const action = fetchCurrentUser();

   action(dispatch);

   expect(dispatch.called).to.be.true;
});

我还没有实现fetchCurrentUser函数 - 只是假设它需要一些"服务器"时间然后它将调用' dispatch()'。

由于异步流,规范失败。如果我在期望之前添加一个101毫秒的setTimeout - 它会通过。

我的代码将使用一些返回promise的DB API,因此async函数最终将如下所示:

//...
return (dispatch) => {
   return dbAPI.fetchUser().then(dispatch(....));
}

所以我试图要求dbAPI并在测试中创建一个sinon.stub()。return(Promise.resolve())并且它也没有工作(我认为,因为存根返回一个已解决的承诺 - 异步函数将像一个同步函数。)

任何想法我应该如何测试那样的异步函数?

感谢, 艾米特。

2 个答案:

答案 0 :(得分:5)

不要用sinon模仿调度,自己编写并在完成时调用Mocha的done()

it('Should work', (done) => {
   const dispatch = () => {
     // Do your tests here
     done();
   };
   const action = fetchCurrentUser();

   action(dispatch)
     // Also allow quick failures if your promise fails
     .catch(done);
})

如果您只是想确保调用调度,那么mocha将会超时。来自异步操作创建者的返回承诺的捕获允许错误显示在正确的位置,并且测试失败而不是超时。

答案 1 :(得分:2)

好吧,我想我找到了一个解决方案:

假设我的异步函数如下所示:

//...
return (dispatch) => {
   return dbAPI.fetchUser().then(dispatch(....));
}

然后我可以按如下方式编写规范:

it('Should work', () => {
   dbAPI.fetchUser = sinon.stub().returns(Promise.resolve({username: 'John'}));

   const dispatch = sinon.spy();
   const action = fetchCurrentUser();

   action(dispatch).then(() => {
      expect(dispatch.called).to.be.true;
   });
});

我不知道这是否是一种解决方法,但它确实有效。我很感激您对更好的方法的看法...

谢谢, 艾米特。