如何在React中测试异步方法?

时间:2016-11-11 12:27:29

标签: javascript unit-testing reactjs mocking enzyme

有人可以帮我测试React组件中基于异步/ Promise的方法吗?例如,我有以下非常简单的React组件(它只是虚拟代码)

import server from './server';

class Button extends Component {
  async handleClick() {
    if (await canDoSomething()) {
      const result = await calculateIt();
      if (result) {
        // will be mocked in my unit test
        await server.sendResultToServer(result);
        localStorage.setItem('sent', 'true');
      }
      localStorage.setItem('sent', 'false');
    }
    if (localStorage.getItem('sent') === 'true') {
      // do something
    }
  }

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

现在在我的测试中我可以用sinon模拟大多数异步方法:

it('should do something', async () => {
  const promise = Promise.resolve();
  sinon.stub(server, 'sendResultToServer', () => promise);
  const wrapper = shallow(<Button />);
  wrapper.find(<button />).simulate('click');
  // this await will be resolved FIRST. Only then
  // await server.sendResultToServer(result); in my code will be resolved
  await promise;
  expect(localStorage.getItem('sent')).to.equal('true');
})

如果您第一次看到此代码,您应该认为一切正常。但不幸的是,事实并非如此。在我的测试中,我正在等待我的承诺await promise;之后的。但实施代码也等待着承诺。因此,当承诺在两个位置完成时,期望在之前运行实现中的代码运行。换句话说:我的测试在要测试的代码之前运行(在我的机器上使用Mocha / Chai / Enzyme测试)。我需要的是逆序。

有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您需要触发点击处理程序:

it('should do something', async () => {
  const promise = Promise.resolve();
  sinon.stub(server, 'sendResultToServer', () => promise);
  const wrapper = shallow(<Select />);
  wrapper.simulate('click')
  await promise;
  expect(localStorage.getItem('sent')).to.equal('true');
})