为什么我需要在操作中包装React / Enzyme状态更改?

问题描述 投票:0回答:1

在我的简单React / ReactDOM / Enzyme单元测试中,我从ReactDOM收到有关将任何突变包装到act()状态的警告。如果我的考试仍然通过,为什么我需要这样做?我有50个左右的React组件,都使用钩子,自定义钩子等,而且我从不包装act(),它们都通过了。

我可以禁用此警告吗?我不想添加多余的代码,这似乎是没有原因的。

警告:

Warning: An update to MyComponent inside a test was not wrapped in act(...).

    When testing, code that causes React state updates should be wrapped into act(...):

    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */

    This ensures that you're testing the behavior the user would see in the browser. Learn more at [redacted]

我的测试:

const App = () => {
  const [isLoaded, setIsLoaded] = useState(false);

  const myOnClick = () => {
    setIsLoaded(true);
  };

  return (
    <div onClick={myOnClick}>
      {isLoaded ? 'Yes' : 'No'}
    </div>
  )
}
describe('My test', () => {
  let wrapper

  beforeAll(() => {
    wrapper = mount(<App />)
  })

  it('renders "no"', () => {
    expect(wrapper.text()).toBe('No')
  })

  describe('When onClick is called', () => {
    beforeAll(() => {
      wrapper.find('div').prop('onClick')()
    })

    it('renders "yes"', () => {
      expect(wrapper.text()).toBe('Yes')
    })
  })
})

CodeSandbox复制:https://codesandbox.io/s/react-169-act-warning-repro-olm8o?expanddevtools=1&fontsize=14&hidenavigation=1&previewwindow=tests

reactjs jestjs enzyme react-dom
1个回答
0
投票

act()首先运行所有相关的useEffect,否则将以异步方式运行。您看不到任何区别,因为您的组件代码中没有useEffect

根据最新版本的Enzyme's docsmount()应该已经在内部用act()包装:

[如果您使用React 16.8+和.mount(),则Enzyme将使用.simulate()包装包括.setProps().setContext().invoke()ReactTestUtils.act()的api,因此您无需手动包装。

我们无法在内部用酶中的.prop()包装.props()(或.act())的结果,因为它将破坏返回值的相等性。但是,您可以使用.invoke()简化代码:

const wrapper = mount(<SomeComponent />);
wrapper.invoke('handler')();
expect(/* ... */);```
© www.soinside.com 2019 - 2024. All rights reserved.