5

我正在尝试使用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 - 它会通过。

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

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

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

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

谢谢,阿米特。

4

2 回答 2

5

不要用 sinon 模拟调度,编写你自己的并done()在完成后调用 Mocha's。

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 将超时。异步操作创建者返回的承诺的捕获允许错误显示在正确的位置,并且测试失败而不是超时。

于 2016-04-05T06:40:52.277 回答
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;
   });
});

我不知道这是否是一种解决方法,但它有效。我会很感激你对更好的方法的意见......

谢谢,阿米特。

于 2016-01-18T18:56:25.127 回答