Jest.js React Testing Library - not wrapped in act()错误

ds97pgxw  于 2023-11-15  发布在  Jest
关注(0)|答案(2)|浏览(127)

我在使用react-testing-library测试切换组件时遇到问题。
单击图标( Package 在按钮组件中)时,我希望文本从“已验证”变为“未验证”。此外,在状态更新时调用一个函数。
然而,点击事件似乎不起作用,我得到下面的错误:

> jest "MyFile.spec.tsx"

 FAIL  src/my/path/__tests__/MyFile.spec.tsx
  component MyFile
    ✓ renders when opened (94 ms)
    ✓ renders with items (33 ms)
    ✕ toggles verification status on click of icon button (100 ms)

  console.error
    Warning: An update to MyFile 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 MyFile (/path/to/myfile.tsx:44:3)
        at ThemeProvider (/users/node_modules/@material-ui/styles/ThemeProvider/ThemeProvider.js:48:24)

      123 |       );
      124 |     } finally {
    > 125 |       setIsLoading(false);
          |       ^
      126 |     }
      127 |   };
      128 |

      at printWarning (node_modules/react-dom/cjs/react-dom.development.js:67:30)
      at error (node_modules/react-dom/cjs/react-dom.development.js:43:5)
      at warnIfNotCurrentlyActingUpdatesInDEV (node_modules/react-dom/cjs/react-dom.development.js:24064:9)
      at dispatchAction (node_modules/react-dom/cjs/react-dom.development.js:16135:9)
      at handleConfirm (src/modules/myfile.tsx:125:7)

字符串
在我的代码中,我有一个这样的函数:

const handleSubmit = async() => {
  if(isLoading) {
    return;
  }

  try {
    setIsLoading(true);
    await myFunctionCalls();
  } catch (error){
    console.log(error)
  } finally {
    setIsLoading(false)
  }
};


我的测试看起来像这样:

test('toggles verification status on click of icon button', async () => {
    renderWithTheme(
    <MyComponent/>,
   );

  const updateVerificationMock = jest.fn();
  const callFunctionWithSerializedPayloadMock =
    callFunctionWithSerializedPayload as jest.Mock;
  callFunctionWithSerializedPayloadMock.mockImplementation(
    () => updateVerificationMock,
  );

    const button = screen.getByRole('button', {name: 'Remove approval'});
    fireEvent.click(button);

    await act(async () => {
      expect(myFunctionCalls).toHaveBeenCalledTimes(1);
    });
    expect(await screen.findByText('unverified')).toBeInTheDocument();
  });


当函数调用一次时,第一个expect通过,但是我有上面的act()错误,而且还有一个失败,因为文本似乎没有从verified切换到unverified
我知道通常act错误是一个等待调用发生的问题,但我认为findByText应该等待,似乎还有另一个问题我在这里没有抓住。

zf2sa74q

zf2sa74q1#

当您单击Remove Approval按钮时,会在此处调用3个aprc函数。
首先,您将加载状态设置为true,因此它将加载,然后调用MyFunctionCalls函数,最后,加载器将在加载状态设置为false后消失。
为了解决这个问题,我们必须先等待加载出现,然后调用myFunctionCalls,然后我们必须等待加载消失。

test("toggles verification status on click of icon button", async () => {
  renderWithTheme(<MyComponent />);

  const updateVerificationMock = jest.fn();
  const callFunctionWithSerializedPayloadMock =
    callFunctionWithSerializedPayload as jest.Mock;
  callFunctionWithSerializedPayloadMock.mockImplementation(
    () => updateVerificationMock
  );

  const button = screen.getByRole("button", { name: "Remove approval" });
  fireEvent.click(button);

  expect(await screen.findByText(/loading/i)).toBeInTheDocument();

  await waitFor(() => {
    expect(myFunctionCalls).toHaveBeenCalledTimes(1);
  });

  await waitForTheElementToBeRemoved(() => {
    expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
  });

  expect(await screen.findByText("unverified")).toBeInTheDocument();
});

字符串
如果你没有加载文本,那么你可以使用act(() => jest.advanceTimersByTime(500));将时间延长到500毫秒。当时间达到500毫秒时,cnrc函数将被解决。

beforeEach(() => {
  jest.useFakeTimers();
})

afterEach(() => {
  jest.runAllPendingTimers();
  jest.useRealTimers()
})

test("toggles verification status on click of icon button", async () => {
  renderWithTheme(<MyComponent />);

  const updateVerificationMock = jest.fn();
  const callFunctionWithSerializedPayloadMock =
    callFunctionWithSerializedPayload as jest.Mock;
  callFunctionWithSerializedPayloadMock.mockImplementation(
    () => updateVerificationMock
  );

  const button = screen.getByRole("button", { name: "Remove approval" });
  fireEvent.click(button);

  act(() => jest.advanceTimersByTime(500));

  await waitFor(() => {
    expect(myFunctionCalls).toHaveBeenCalledTimes(1);
  });

  act(() => jest.advanceTimersByTime(500));

  expect(await screen.findByText("unverified")).toBeInTheDocument();
});

puruo6ea

puruo6ea2#

试试这个:

// [...]

     fireEvent.click(button);

     await waitFor(() => {
          expect(myFunctionCalls).toHaveBeenCalledTimes(1),
          expect(screen.findByText('unverified')).toBeInTheDocument()
        });

     // End of test

字符串

相关问题