簡體   English   中英

意外的 afterAll 在 Jest/Testing Library 測試套件中執行

[英]Unexpected afterAll execution in Jest/Testing Library test suite

我正在 React 組件中測試一些異步行為,包括加載和錯誤狀態。 我通過使用設置狀態的不同describe塊來接近不同的狀態,如下所示:

jest.spyOn(global, 'fetch');

describe('The App', () => {
  const promiseWithDelay = (json, delay=0) =>
    new Promise(resolve =>
      setTimeout(
        () => resolve({
          ok: true,
          json: () => json
        }), delay
      )
    );

  describe('given data loading', () => {
    beforeEach(async () => {
      global.fetch.mockImplementationOnce(() =>
        promiseWithDelay(someData, 50)
      );

      await waitFor(() => render(<App />));
    });

    // ... successful tests for a loading state here
  });

  describe('some other tests', () => {
    // ... more setup and other tests here
  });
});

我正在通過模擬fetch創建加載狀態

測試全部通過,但我收到Warning: Can't perform a React state update on an unmounted component. 錯誤,我認為這是因為在第二個describe塊中的測試開始運行之前,第一個 describe 塊的render沒有完全解決。

為了清除錯誤,我原本想在第一個describe塊中包含一個afterAll函數來等待創建加載狀態的Promise解決,如下所示:

describe('The App', () => {
  // ... etc

  describe('given data loading', () => {
    beforeEach(async () => {
      // ... etc
    });

    // ... successful tests for a loading state here

    afterAll(async () => {
      await waitFor(() => {
        expect(screen.queryByTestId('some-rendered-content')).toBeInTheDocument();
      });
    });
  });

  describe('some other tests', () => {
    // ... more setup and other tests here
  });
});

這並沒有清除錯誤,但是將afterAll函數更改為afterAll函數可以afterEach

完全困惑,我添加了一些控制台日志來查看什么時候發生了什么,並發現了這一點:

// afterEach console logs

beforeEach: Starting loading test
test: Testing loading
afterEach: Cleaning up from loading test
afterEach: Waiting for content to render
afterEach: Waiting for content to render
afterEach: Cleaned up from loading test
some other test: Starting next test
// afterAll console logs

beforeEach: Starting loading test
test: Testing loading
afterAll: Cleaning up from loading test
afterAll: Waiting for content to render
(console.error): Warning: Can't perform a React state update on an unmounted component. (etc.)
afterAll: Waiting for content to render
afterAll: Waiting for content to render
... afterAll: Waiting for content to render logs many times here
some other test: Starting next test

任何人都可以解釋這里的操作順序以及可能導致afterAll但不是afterEach警告的afterEach嗎?

警告意味着被測試的組件有一些測試沒有等待的異步副作用(在這個測試套件中由fetch表示)。

afterAll應用於各自describe一組測試,如果有多個測試,其中一些測試不會受到waitFor中的afterAll提供的延遲的影響。

正如與測試框架的集成所預期的那樣,React 測試庫會進行清理以使測試不會相互影響,而afterEach是正確的地方。 正如文檔所述,

如果您使用的測試框架支持 afterEach 全局(如 mocha、Jest 和 Jasmine),則默認情況下每次測試后都會自動調用 Cleanup。

編寫測試的正確方法是在 RTL 清理之前等待組件內部的副作用完成。 這需要在每個測試中至少等待與副作用持續時間(50 毫秒)相同的時間,並且需要更多時間才能刷新承諾。 waitFor的使用允許不依賴於實現細節。 由於副作用會影響測試結果,對於正確的位置waitForbeforeEach或測試本身,而不是afterEachafterAll

同樣await waitFor(() => render(<App />))沒有什么用處,因為它僅對拋出錯誤的函數有效,最常見的是斷言。 它可以簡化為render(<App />)

暫無
暫無

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

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