[英]Update not wrapped in act(…) and the mock function not firing. react-testing-library, jest
[英]Jest + react-testing-library: Warning update was not wrapped in act()
我正在使用 react-testing-library 測試我的組件,並且測試效果很好。 我只是無法擺脫這個警告,fireEvent 應該被包裝在開箱即用的行為中,但我試圖再次包裝它並沒有幫助。
這是我的測試用例。
it.only("should start file upload if file is added to the field", async () => {
jest.useFakeTimers();
const { getByTestId } = wrapper;
const file = new File(["filefilefile"], "videoFile.mxf");
const fileInput = getByTestId("drop-zone").querySelector(
"input[type='file']"
);
fireEvent.change(fileInput, { target: { files: [file] } });
act(() => {
jest.runAllTimers();
});
await wait(() => {
expect(
initialProps.uploadItemVideoFileConnect.calledWith(file, 123)
).toBe(true);
});
});
這是警告
Warning: An update to UploadButtonGridComponent 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 */
該問題是由 Component 內部的許多更新引起的。
我得到了同樣的,這就是我解決問題的方法。
await act( async () => {
fireEvent.change(fileInput, { target: { files: [file] } });
});
在源代碼中, fireEvent
已經包含在act()
。
該問題可能與此問題有關,其中異步邏輯(例如useEffect
)正在觸發 fireEvent 之外的狀態更改:
https://github.com/kentcdodds/react-testing-library/issues/281
(如果沒有看到您的組件實現,很難確定這是否正是您的情況。)
顯然有計划在未來的版本中包含異步處理,所以這不會成為問題。
所以這很難總結,但我會嘗試。
act
警告只是告訴您在您的功能組件中發生了一些您沒有測試的事情。
假設我們正在渲染這樣的待辦事項列表
<ul>
{loading ? (
<p>Fetching todos</p>
) : (
<>
{appData.todoList.slice(0, 15).map((item) => {
const { id, title } = item;
return (
<li key={id} data-testid={id}>
<Link to={`/item/${id}`}>{title}</Link>
</li>
);
})}
</>
)}
</ul>
下面的測試用例將拋出act
警告
import { waitFor, screen, waitForElementToBeRemoved } from "@testing-library/react";
it("Renders <TodoList /> component", async () => {
render(<TodoList />);
await waitFor(() => expect(axios.get).toHaveBeenCalledTimes(1));
await waitForElementToBeRemoved(() => screen.getByText(/Fetching todos/i));
expect(axios.get).toHaveBeenCalledTimes(1);
todos.slice(0, 15).forEach((td) => {
expect(screen.getByText(td.title)).toBeInTheDocument();
});
});
但是如果你像這樣重新排序await
行
await waitForElementToBeRemoved(() => screen.getByText(/Fetching todos/i));
await waitFor(() => expect(axios.get).toHaveBeenCalledTimes(1);
act
警告消失。 這是有道理的。 您可以確保您的用戶不再看到加載指示器。
還有其他情況,所以請繼續閱讀 Kent Dodds 的這篇文章。
https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning
在act
之前添加await
await act(() => {
/* fire events that update state */
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.