Jest反应测试:延迟后检查状态

时间:2017-08-03 08:24:28

标签: javascript reactjs unit-testing jestjs

我真的很困惑在Jest文档的帮助下尝试创建测试https://facebook.github.io/jest/docs/timer-mocks.html#content

我尝试检查容器安装时的状态,然后几秒后,我在状态下手动设置值(使用setTimeout())。

我在Main的componentDidMount中有一个函数,如下所示:

componentDidMount() {
    this.setStateAfterDelay();
}

该功能的作用是:

setStateAfterDelay = () => {
    setTimeout(() => {
        this.setState({ fruits: ['banana', 'apple', 'orange', 'vodka', 'kiwi'] });
    }, 1500);
}

我完成了第一部分:

const component = mount(<Main />);
expect(component.state().fruits).toEqual(null);

但我不知道如何再次检查状态,比方说2000ms?

感谢任何帮助:)

4 个答案:

答案 0 :(得分:12)

我还没有真正测试过这段代码。但是,我认为类似的东西应该可行。

const fruits = ['banana', 'apple', 'orange', 'vodka', 'kiwi'];

it('mock setTimeout test', () => {
 jest.useFakeTimers();
 setTimeout(() => {
   expect(component.state().fruits).toEqual(fruits);
 }, 1500);
 jest.runAllTimers();
});

答案 1 :(得分:2)

您无需延迟测试,只需在声明前调用jest.runAllTimers()即可。

const fruits = ['banana', 'apple', 'orange', 'vodka', 'kiwi'];

it('initializes the fruits state', () => {
 jest.useFakeTimers();
 jest.runAllTimers();
 expect(component.state().fruits).toEqual(fruits);
});

如果您要进行多次测试,也可以在useFakeTimers()中致电beforeEach,并且runAllTimers()可以在另一个beforeEach内部,因此您无需重复自己

答案 2 :(得分:0)

虽然jest可以轻松地运行异步代码,但是您可以使用promise和setTimeout组合稍等一下。例如,此代码将等待2秒:

await new Promise((r) => setTimeout(r, 2000));

完整样本测试。不要忘记在回调函数之前添加async标志:

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});

答案 3 :(得分:0)

我知道这是关于20秒后如何检查某事的问题。但这也可能表示您不想测试20秒,因为有时重要的是是否使用正确的输入执行了某些操作。在这种情况下,您可以稍微重组代码,以便可以传递分派函数。例如

    function abc() {
        return dispatch => {
            return Promise.then(res => {})  // this would take 20 seconds
        }
    }

由于传入了dispatch,因此您可以轻松地在测试代码中使用以下内容。

    const dispatch = Jest.fn()
    abc(dispatch)
    expect(dispatch).toBeCalled()

当然,假设您不关心是否20秒,而更关心工作流程。