iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0

生命週期

複習一下昨天提到的幾個生命週期!

  • beforeAll(fn, timeout) :在該區域最一開始執行一次
  • beforeEach(fn, timeout) :在該區域每個測試運行前執行一次
  • afterEach(fn, timeout) :在該區域每個測試執行完時都執行一次
  • afterAll(fn, timeout):在該區域所有測試都執行完後運行一次

測試的清除

首先來看一下底下例子:

共用某狀態時,第一個區塊內的 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');
  });
})

https://ithelp.ithome.com.tw/upload/images/20221003/20139066i5fypdNaKG.png
在這時候可以透過 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";
});

接著也要補充 React Testing Library 透過調用 JestafterEach 實現的 cleanup 卸載功能,在測試途中我們很常會使用 render 方法來協助渲染 React Trees,而 React Testing Library 實際上於每次運行完 render 後也有透過調用生命週期 afterEach 並透過 cleanup 幫我們卸載元素,避免互相污染:

// 範例程式碼取自官方文件
import {cleanup, render} from '@testing-library/react'
import test from 'ava'

// 在使用 Jest 的情況下無需特別撰寫,已幫忙自動調用
test.afterEach(cleanup)

test('renders into document', () => {
  render(<div />)
  // ...
})

// ... more tests ...

另外,當不希望 mock 的函式值互相影響時也可以透過 afterEach 搭配 Jest 的 clearAllMocks() 清除現有的 mock 的數據:

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

今天學習到一些測試的清除方式,透過在生命週期還原值或 mock 數據,降低各個測試間互相干擾。


參考文章

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


上一篇
關於測試的作用域
下一篇
關於測試的學習小總結篇
系列文
<< 測試魔法 >> 這能動嗎?不然就測測看好了!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言