[英]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.