我是 React 测试新手,我很难解决以下问题:
我正在尝试模拟输入 onChange 事件。它是一个文本输入,用于过滤表中的结果。 InteractiveTable
有一个受控输入字段 (ControlledInput
) 和 Facebook 的 FixedDataTable
实例。
这是测试:
let filter = ReactTestUtils.findRenderedComponentWithType(component, ControlledInput);
let input = ReactTestUtils.findRenderedDOMComponentWithTag(filter, 'input');
input.value = 'a';
ReactTestUtils.Simulate.change(input);
console.log(component.state);
输入更改时,组件会使用输入的值更新其状态,但由于 setState
是异步的,因此 console.log 将注销以前的状态,并且我无法查询用于测试的组件结构,因为它尚未更新。我错过了什么?
编辑:要明确的是,如果我在 setTimeout 中进行断言,它就会通过,所以这肯定是 setState 的异步性质的问题。
我找到了一个解决方案,我覆盖了组件的 componentDidUpdate
方法:
component.componentDidUpdate = () => {
console.log(component.state); // shows the updated state
let cells = ReactTestUtils.scryRenderedComponentsWithType(component, Cell);
expect(cells.length).toBe(30);
done();
};
如果组件有自己的 componentDidUpdate 方法,这是不可能的,所以这不是一个好的解决方案。这似乎是一个很常见的问题,但我找不到解决方案。
最佳答案
通常,当我在测试时遇到类似的场景时,我会尝试将事情分解一点。在当前的测试中(取决于您的测试框架风格),您可以模拟组件的 setState
方法,并简单地确保在模拟更改时以您期望的方式调用它。
如果您想要进一步覆盖,在不同的测试中,您可以使用一些模拟数据调用真正的 setState
,然后使用 callback对渲染的内容做出断言,或确保调用其他内部方法。
或者:如果您的测试框架允许simulating async东西,你也可以尝试调用它并一次性测试整个事情。
关于javascript - 使用异步 setState 进行 React 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35225848/