Issue
This is my JEST test case. I wrapped my state changing actions into act
. But it doesn't help.
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);
});
I still see a warning message:
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
Test passes now, but fails if I remove setTimeout
.
So I want 2 things: to get rid of warning and setTimeout.
Any ideas highly appreciated.
Solution
To get rid of the warning message and setTimeout
, you can try using async/await
along with the waitFor
function which will ensure that all state updates are properly wrapped within act()
. Below is the code for the same:
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,
]);
});
});
Answered By - mandy8055
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.