![](/img/trans.png)
[英]Jest + react-testing-library: Warning update was not wrapped in act()
[英]Update not wrapped in act(…) and the mock function not firing. react-testing-library, jest
我希望得到一些幫助。 我一直在研究它太久,認為沒有提出問題。
提前感謝您的時間和關注,
我已經搜索了互聯網並嘗試了很多東西,但我仍然沒有運氣 - 這就是問題所在。
總而言之-我正在關注https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning
將 react-testing-library 與 jest 結合使用 - 並遇到兩個問題
Warning: An update to Login inside a test was not wrapped in act(...).
我真的認為我已經正確連接了所有東西 - 不確定我錯過了什么。 在模擬里面我可以放一個 console.log 並且可以確認模擬確實被調用了。
/*
Test
*/
it('should call props.fetchSignIn with the username and password', async () => {
const promise = Promise.resolve({
email: 'test@circulate.social',
firstName: 'Mike',
lastName: 'A',
});
const fetchSignIn = jest.fn(() => promise);
const { queryByTestId, queryByPlaceholderText } = renderLogin({
fetchSignIn,
});
const emailInput = queryByPlaceholderText('joedoe@gmail.com');
const passwordInput = queryByPlaceholderText('password');
const submitButton = queryByTestId('submitButton');
fireEvent.change(emailInput, {
target: { value: 'mike@circulate.social' },
});
fireEvent.change(passwordInput, { target: { value: 'Password1!' } });
fireEvent.click(submitButton);
// I expected this to fail from the parameters being wrong
expect(fetchSignIn).toHaveBeenCalledWith('asf');
await act(() => promise);
});
/*
Functional Component using the `useState(...)` hooks
onFormFinished is the form `onSubmit` handler
*/
const handleSignIn = async (
email: string,
password: string
): Promise<UserContextType['user']> => {
setIsLoginInFlight(true);
try {
const result = await props.fetchSignIn(email, password);
setIsLoginInFlight(false);
return result;
} catch (error) {
// Other logic removed
};
const onFormFinish = async (values: FormValues): Promise<void> => {
const { email, password } = values;
const signInResult = await handleSignIn(email, password);
// Other logic removed
};
發生了兩件事 1 - 警告 2 - 測試失敗,因為fetchSignIn
從未被調用
預期結果 由於調用了fetchSignIn
而導致測試失敗,但參數錯誤
歡迎任何意見或要求澄清。
謝謝
我在提交 forms 和 Ant 設計 4 + react-testing-library 時也遇到了一些麻煩。 經過一些實驗后,我始終使用 data-testid 提交 forms:
<Button data-testid="submit" htmlType="submit">Submit</>
// Form element has onFinish attribute
// in test
fireEvent.click(rtl.getByTestId("submit"));
expect(...);
這不是 RTL 所提倡的(應避免使用 datat-testid,像真正的用戶一樣進行測試),但我可以接受。
但是根據https://github.com/ant-design/ant-design/issues/21272觸發提交事件應該也可以,我一定會試一試。
與喜劇接壤,絕對不是解決問題的正確方法。 但是一種解決問題的方法 - 除了完全避免使用onFinish
並依賴按鈕上的onClick
之外,唯一對我有用的方法。
那么訣竅實際上是將expect(...)
包裝在setTimeout(...)
// click || submit - both seemed to work for me
fireEvent.submit(submitButton);
setTimeout(() => {
expect(fetchSignIn).toHaveBeenCalledWith('asf');
});
it('should call props.fetchSignIn with the username and password', async () => {
const promise = Promise.resolve({
email: 'test@circulate.social',
firstName: 'Mike',
lastName: 'A',
});
const fetchSignIn = jest.fn(() => promise);
const { queryByTestId, queryByPlaceholderText } = renderLogin({
seedEmail: 'aasdf',
seedPassword: 'asdf',
fetchSignIn,
});
const emailInput = queryByPlaceholderText('joedoe@gmail.com');
const passwordInput = queryByPlaceholderText('password');
const submitButton = queryByTestId('submitButton');
fireEvent.change(emailInput, {
target: { value: 'mike@circulate.social' },
});
fireEvent.change(passwordInput, { target: { value: 'Password1!' } });
// click || submit - both seemed to work for me
fireEvent.submit(submitButton);
setTimeout(() => {
expect(fetchSignIn).toHaveBeenCalledWith('asf');
});
await act(() => promise);
});
這是有人在 GitHub 問題https://github.com/ant-design/ant-design/issues/21272#issuecomment-628607141上向我提出的,所以在 GH 上向 @ildarnm 大喊
讓我們先解決您的第二個問題。
開玩笑並沒有意識到正在調用模擬
我發現使用 ant 設計 forms 進行測試也很棘手。 經過一些挖掘和實驗,似乎模擬“點擊”不會觸發 onFinish,而是模擬“提交”。 使用 Jest 和 Enzyme 對以下示例進行成像:
export default MyForm = () => {
<Form onFinish={onFinish}>
<Form.Item>
<Button htmlType='submit'>Submit</Button>
</Form.Item>
</Form>
}
it('should trigger onFinish if submit', () => {
const onFinish = jest.fn();
const wrapper = mount(<MyForm onFinish={onFinish}/>);
wrapper.find('button').simulate('submit');
await sleep(200)
expect(onFinish).toHaveBeenCalled();
})
我自己也在為第一個問題苦苦掙扎:
警告:測試中登錄的更新未包含在 act(...) 中
請注意,只有在出現驗證錯誤時才會發生這種情況,因為在它們的表單實現中存在內部 state 更改。
首先,這是一個警告,意思是如果你不介意日志被污染可以忽略它。
其次,只有在“開發”而不是“生產”時才發出警告。
如果你確實想讓它消失,這就是我正在采取的“hacky”方式(我不知道是否有更好的方式):
it('should trigger onFinish if submit', () => {
const onFinish = jest.fn();
const wrapper = mount(<MyForm onFinish={onFinish}/>);
await act(async () => {
wrapper.find('button').simulate('submit');
})
await sleep(200)
wrapper.update()
// check errors here
expect(onFinish).not.toHaveBeenCalled();
})
這在這里正式記錄: https://github.com/enzymejs/enzyme
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.