在我的简单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
act()
首先运行所有相关的useEffect
,否则将以异步方式运行。您看不到任何区别,因为您的组件代码中没有useEffect
根据最新版本的Enzyme's docs,mount()
应该已经在内部用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(/* ... */);```