这是我的 JEST 测试用例。我将状态更改操作封装到
act
中。但这没有帮助。
it('ListInput add item', done => {
const valueTyped = '123.1.1.1';
const formItemDataPath = ['proxy', 'rules', 'excludedAddresses'];
let listInputInternalInput;
let listInputAddItemButton;
let c;
let formValue;
const handleFormChange = v => {
formValue = v;
};
act(() => {
const ListInputForm = () => {
return (
<div>
<BasicForm initialValue={clone(bondingFormData)} onChange={handleFormChange}>
<BasicFormItem name={formItemDataPath} label={'listInput'}>
<ListInput data-testid='listInput' />
</BasicFormItem>
</BasicForm>
</div>
);
};
const { container } = render(<ListInputForm />);
c = container;
});
listInputInternalInput = c!.querySelector('Input');
listInputAddItemButton = c!.querySelector('[type=button]');
act(() => {
fireEvent.change(listInputInternalInput, { target: { value: valueTyped } });
fireEvent.click(listInputAddItemButton);
});
//
setTimeout(() => {
expect(getProperty(formValue!, formItemDataPath)).toEqual([
...getProperty(bondingFormData, formItemDataPath),
valueTyped,
]);
done();
}, 1000);
});
我仍然看到一条警告消息:
at recipe (.../BasicForm.tsx:29:17)
console.error
Warning: An update to BasicForm 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 https://reactjs.org/link/wrap-tests-with-act
at BasicForm (.../BasicForm.tsx:65:11)
at div
at ListInputForm
测试现在通过,但如果我删除
setTimeout
,则会失败。
所以我想要两件事:摆脱警告和设置超时。
任何想法都值得高度赞赏。
要摆脱警告消息和
setTimeout
,您可以尝试将 async/await
与 waitFor
函数一起使用,这将确保所有状态更新都正确包装在 act()
中。下面是相同的代码:
it('ListInput add item', async () => {
// ...Rest of code
await act(async () => {
// ...
});
// ...
await act(async () => {
fireEvent.change(listInputInternalInput, { target: { value: valueTyped } });
fireEvent.click(listInputAddItemButton);
});
await waitFor(() => {
expect(getProperty(formValue!, formItemDataPath)).toEqual([
...getProperty(bondingFormData, formItemDataPath),
valueTyped,
]);
});
});