簡體   English   中英

Jest + react-testing-library:警告更新未包含在 act() 中

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM