簡體   English   中英

如何在使用 React 測試庫的集成測試中避免“行為”警告

[英]How to avoid “act” warnings in a integration tests with React Testing Library

我在我的單頁應用程序的集成測試中渲染組件,並嘗試遵循從登陸頁面到測驗/memory 游戲的第一個問題的快樂路徑。

Warning: An update to GamePlay inside a test was not wrapped in act(...).

第二行是觸發多個警告的行...

    const firstItem = getAllByRole("listitem")[0]
    userEvent.click(firstItem)

它單擊列表中的第一個選項,該選項會導致游戲組件呈現。 該組件顯示一個單詞 5000 毫秒,然后使用在組件的 useEffect 掛鈎(下)中設置的 setTimeout 隱藏它。 在此例程中還禁用和啟用了答案輸入字段。

    function hideQuestion() {
        setInputDisabled(false)
        setDisplayWord(false)
    }

    const [displayWord, setDisplayWord]= useState(true);

    useEffect(()=>{
        setTimeout(hideQuestion, 5000)
    },[displayWord])

    const [inputDisabled, setInputDisabled] = useState(true);

從閱讀中我認為這可能是 setTimeout 的這種使用是負責任的,但我嘗試過的任何緩解措施都沒有做任何事情。 我嘗試將點擊線包裝在“act” function 中,但什么也沒做。 我嘗試使測試異步並等待該行,但又什么也沒做-我仍然收到此錯誤(以及幾個類似的錯誤)...

  console.error
    Warning: An update to GamePlay 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 GamePlay (/home/user/code/spellingapp/src/components/GamePlay.js:3:20)
        at MainPage (/home/user/code/spellingapp/src/components/MainPage.js:8:29)
        at Route (/home/user/code/spellingapp/node_modules/react-router/cjs/react-router.js:470:29)
        at Switch (/home/user/code/spellingapp/node_modules/react-router/cjs/react-router.js:676:29)
        at Router (/home/user/code/spellingapp/node_modules/react-router/cjs/react-router.js:99:30)
        at BrowserRouter (/home/user/code/spellingapp/node_modules/react-router-dom/cjs/react-router-dom.js:67:35)
        at App (/home/user/code/spellingapp/src/App.js:16:29)

       5 |   function hideQuestion() {
       6 |     // console.log("I have hidden the word and enabled the text box")
    >  7 |     setInputDisabled(false)

我嘗試閱讀這篇文章: https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning

但我很難完全理解它並將其與我自己的代碼聯系起來。 我認為它的要點是,當出現“意外的” state 更改時,您會收到這些警告,但我看不出我應該如何讓我的預期發生變化。 我的應用程序是一個實時游戲,所以整個事情都通過計時器運行 - 一個計時器完成,另一個計時器開始。 我不想跑完整整 10 分鍾的游戲,所以它可以整齊地完成。 我只是想測試從登陸頁面到第一次交互作為核心集成邏輯的冒煙測試。

現在我能想到的就是制作一個只有一個問題的測試夾具,這樣我就可以端到端地運行整個游戲,但是當我當前的測試運行良好(除了警告)並且做我想要的一切時,這似乎有點過頭了現在就去做。 我將不勝感激任何指示或建議,即使我只是在吠叫錯誤的樹。 謝謝!

以下是您可以做的幾件事:

  • 警告告訴您,您的應用程序在測試完成后繼續運行,因此在運行期間發生了您沒有簽入測試並且沒有等待的其他事情。 因此,如果您對所測試的內容感到滿意,請注意並保持這種狀態。
  • 您可以通過提供選項來使您的應用程序更具可測試性。 例如,您可以有一個可選的道具來指示計時器中等待的時間量,以便您可以在測試中將其設置為 0 或較小的數字。
  • 您可以模擬計時器:
beforeEach(jest.useFakeTimers);
afterEach(jest.useRealTimers);

test("your game", async () => {
  const { getAllByRole } = render(<Game />);
  // [...]
  const firstItem = getAllByRole("listitem")[0]
  userEvent.click(firstItem)
  act(() => jest.advanceTimersByTime(5000));
  // [...]
  act(() => jest.advanceTimersByTime(5000));
  // [...]
});

暫無
暫無

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

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