使用Jest + Enzyme API模拟调用进行测试无法运行

时间:2019-02-15 00:59:00

标签: javascript reactjs jestjs enzyme

我有一个我无法理解的问题,我希望有人可以帮助我。

这是我的测试:state.messages是一个空数组,在要运行的函数中,api.botReply被调用0次。

state.typing设置为true,所以我知道我正在运行该函数。

test('test to resolve data from botReply', done => {
    const wrapper = shallow(<Bot />);

    api.botReply = jest.fn(() =>
        Promise.resolve(wrapper.setState({ typing: false }))
    );

    wrapper.instance().sendReply();

    setImmediate(() => {
        wrapper.update();
        console.log(wrapper.state('typing'));
        console.log(wrapper.state('messages'));
        expect(api.botReply).toHaveBeenCalledTimes(1);
        done();
    });
});

这是运行的功能:

 sendReply = () => {
    this.setState({ typing: true });
    api.botReply()
      .then(reply => {
        this.setState({ messages: [...this.state.messages, reply], typing: false });
      })
  };

1 个答案:

答案 0 :(得分:1)

丢弃承诺链并使用随机延迟会导致类似这样的比赛条件。

由于在测试中提供了承诺,因此应将其链接起来以保持正确的控制流程。将Jest间谍指定为方法不是一个好习惯,因为以后不会对其进行清理。应许应使用reply而不是设置状态来解决。

应该是这样的:

test('test to resolve data from botReply', async () => {
    const wrapper = shallow(<Bot />);
    const promise = Promise.resolve('reply')'

    jest.spyOn(api, 'botReply').mockImplementation(() => promise);

    wrapper.instance().sendReply();
    expect(wrapper.state('typing')).toBe(true);
    await promise;
    expect(api.botReply).toHaveBeenCalledTimes(1);
    expect(wrapper.state('typing')).toBe(false);
});