javascript - 使用异步 setState 进行 React 测试

标签 javascript testing reactjs

我是 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/

相关文章:

javascript - 试图模拟 API 响应延迟 : Cannot read property 'then' of undefined

javascript - 显示选定区域的值(JavaScript 图表)

javascript - mori库的sortBy稳定吗?

javascript - 获取月份差异javascript

html - 元素无意中随着内容的变化而移动

reactjs - 如何将React js array[]转换为iOS中的NSArray和Android中的string[]?

javascript - HTMLCollection 困惑

testing - TestCafe、CircleCI 2.0 和 SauceLabs——无法让这个组合发挥作用

android - 在 Android : ProviderTestCase2 or RenamingDelegatingContext? 上测试数据库

testing - 软件开发工具——从用户目标到测试