Try   HackMD

測試的清除

  • 測試的清除

    目的:避免共用 Context 而導致測試結果錯誤。

    需注意:避免在 expect 後做清掃處理,原因為假如一個測試案例發生錯誤,卻在斷言時拋出 AssertionError 後停止,可能會導致在該測試以後的測試都受到影響。

    範例:

    共用某狀態時,第一個區塊內的 test 去修改了狀態 data 的值,也會導致第二個 test 內的 data 運行失敗。

    ​​​​    const data = {
    ​​​​      key: 'originValue'
    ​​​​    }
    
    ​​​​    describe('test change origin data', ()  => {
    ​​​​      test("change origin value", () => {
    ​​​​        data.key = 'chageValue';
    ​​​​        expect(data.key).toBe('chageValue');
    ​​​​      });
    ​​​​      test("test failed", () => {
    ​​​​        expect(data.key).toBe('originValue');
    ​​​​      });
    ​​​​    })
    

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    在這時候可以透過 afterEach 在每次測試執行完成後將狀態改回原本的值:

    ​​​​    const data = {
    ​​​​      key: "originValue",
    ​​​​    };
    ​​​​    // 透過 afterEach 改回原本的值
    ​​​​    afterEach(() => {
    ​​​​      data.key = "originValue";
    ​​​​    });
    
    ​​​​    describe("test change origin data", () => {
    ​​​​      test("change origin value", () => {
    ​​​​        data.key = "chageValue";
    ​​​​        expect(data.key).toBe("chageValue");
    ​​​​      });
    ​​​​      test("test failed", () => {
    ​​​​        expect(data.key).toBe("originValue");
    ​​​​      });
    ​​​​    });
    

    當然改成 beforeEach 於每次測試運行前執行一次也一樣可以順利解決測試間互相干擾的問題

    ​​​​    beforeEach(() => {
    ​​​​      data.key = "originValue";
    ​​​​    });
    

常見使用方式:

  • 使用 beforeEach / afterEach 在每次測試執行完成後將狀態改回原本的值。
  • 補充:
    • cleanup 卸載功能。
      React Testing Library 透過調用 Jest 的 afterEach 來讓在測試過程時當我們 render 渲染 React Trees 後將元素卸載,避免互相污染。

      以上述範例延伸:

      ​​​​​​​​// 範例程式碼取自官方文件
      ​​​​​​​​import {cleanup, render} from '@testing-library/react'
      ​​​​​​​​import test from 'ava'
      
      ​​​​​​​​// 在使用 Jest 的情況下無需特別撰寫,已幫忙自動調用
      ​​​​​​​​test.afterEach(cleanup)
      
      ​​​​​​​​test('renders into document', () => {
      ​​​​​​​​  render(<div />)
      ​​​​​​​​  // ...
      ​​​​​​​​})
      
      ​​​​​​​​// ... more tests ...
      
    • clearAllMocks() :可搭配 afterEach 來清除現有的 mock 的數據。

      ​​​​​​​​afterEach(() => {
      ​​​​​​​​  jest.clearAllMocks();
      ​​​​​​​​});
      

參考文章
https://codewithhugo.com/jest-stub-mock-spy-set-clear/
https://testing-library.com/docs/react-testing-library/api/#cleanup