簡體   English   中英

Jest 無法在未安裝的組件上執行 React state 更新 + 應將反應 state 更新打包成行為

[英]Jest can't perform a React state update on an unmounted component + react state updates should be wrapped into act

所以我正在嘗試測試表單輸入。 首先表單應該顯示一個錯誤,然后在輸入一個值后,用戶單擊一個按鈕,錯誤應該被刪除。
我想我明白為什么會這樣,但我不知道如何測試這個功能。

我有條件地呈現錯誤消息並更新 state 所以我知道這可能就是為什么它告訴我將我的測試包裝在act()中。 我還告訴模擬服務器發送錯誤 state 並且我想可能是因為我覆蓋了初始處理程序,它只會以我定義的錯誤 state 響應。 那也不行。

我不確定如何准確地測試它,因為我是測試新手。 我真的很感激任何幫助。

這里是測試 function:

it('clears validation error after username field is updated', async () => {
  let validationError;
  server.use(generateValidationError('username', 'Username cannot be null'));
  setup();

  await act(async () => {
    userEvent.click(button);
    validationError = await screen.findByText('Username cannot be null');
    userEvent.type(usernameInput, 'username001');
    userEvent.click(button);
    expect(validationError).not.toBeInTheDocument();
  });
});

由於在組件中設置 state 或異步執行某些操作可能需要“一些時間”,因此您應該將您的情況視為潛在的類似承諾的情況。

為確保您的測試始終等待發生的任何更改,您可以使用waitFor方法並使用您的代碼添加回調 function 以檢查一些 state。 這是來自React 測試庫

it('clears validation error after username field is updated', async () => {
  let validationError;
  server.use(generateValidationError('username', 'Username cannot be null'));
  setup();

  await act(async () => {
    userEvent.click(button);
    userEvent.type(usernameInput, 'username001');
    userEvent.click(button);

    await waitFor(async () => {
      validationError = await screen.findByText('Username cannot be null');
      expect(validationError).not.toBeInTheDocument();
    });
  });
});

小費
當您斷言包含 DOM 元素的內容時,在您執行某些操作后始終 select 該元素(在您的情況下更改驗證 state 在您的情況下單擊按鈕后)。

在上面的代碼中,我根據上述提示更改了該選擇器的 position。

在方法方面,我會:

  1. 測試錯誤最初是可見的
  2. 點擊按鈕
  3. 測試錯誤已消失

如果要使用act() ,通常將斷言放在其 function 主體之外,請參閱https://reactjs.org/docs/testing-recipes.html#act

我什至不確定您是否需要act() 官方測試庫文檔中的示例似乎可以滿足您的需求:

這真是個愚蠢的錯誤。 我遇到的第一個錯誤是因為我在成功提交后隱藏了我的表單。 因此該組件將卸載,然后我將無法對其進行測試。 我通過分別測試每個字段並確保它沒有成功提交表單來找到解決方法。

通過修復上述錯誤,我不再需要使用 act() 了,因為我沒有收到任何開玩笑的錯誤。 之后測試順利通過。

it.each`
      field         | message                      | label
      ${'username'} | ${'Username cannot be null'} | ${'Username'}
      ${'email'}    | ${'Email cannot be null'}    | ${'Email'}
      ${'password'} | ${'Password cannot be null'} | ${'Password'}
    `(
      'clears validation error after $field field is updated',
      async ({ field, message, label }) => {
        server.use(generateValidationError(field, message));
        setup();
        userEvent.click(button);
        const validationError = await screen.findByText(message);
        const inputByLabel = screen.getByLabelText(label);
        userEvent.type(
          inputByLabel,
          label === 'Email' ? 'user@testuser.com' : 'username001'
        );
        //this line was needed to stop the form from submitting
        userEvent.type(confirmPasswordInput, 'newpassword');
        userEvent.click(button);
        await waitFor(() => {
          expect(validationError).not.toBeInTheDocument();
        });
      }
    );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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