iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0
自我挑戰組

為了成為更好的前端,我開始在乎的那些事系列 第 13

[Day 13] 測試思維 & 單元測試 - (9) 每個測試都該是獨立的,那些你該清的 api mock data

  • 分享至 

  • xImage
  •  

為什麼要清除 mocking api function?

先說最終目的:避免每個 test case 的結果互相干擾

在單元測試的藝術中 (Section 8.2.4) 中有提到:

Laziness in cleanup—If you’re too lazy to clean up your database after testing,
your filesystem after testing, or your memory-based objects, consider moving to
a different profession. This isn’t a job for you

意思就是:

如果你在測試後太懶惰以至於不清理你的數據庫、文件系統或基於內存的對象,那麼考慮轉行。這個工作不適合你

 

雖然這句話還蠻重的,不過也大大凸顯出清除測試資料的重要性,當我們單元測試的測試資料互相干擾時,我們最後測出的結果就不會是準確的,就無法具有 可信任的 的特性,那我們做的測試其實就沒有意義了

 

不同的 clean up utils

當我們在 mocking api 時,是將 api function 覆寫成 jest.fn,接著在 jest.fn 客製化我們的 api response

jest.fn 會去記錄一些我們 call api 的過程,像是:

  • 呼叫了幾次
  • 呼叫時帶了什麼參數

 

這時候,我們就可以利用以下三個 utils 來幫我們清除每個 test cases 不同類型的資料:

  • mock.mockClear()
  • mock.mockReset()
  • mock.mockRestore()

這三個 util 各有不同的主要功能,就讓我們來看一下吧~

 

mock.mockClear()

會覆寫掉 mock api 相關的紀錄,像是 呼叫的次數產生的實例數量 等,但不會清除需要引入的 input 或輸出的 output 等條件

主要目的 mock 值 是否被移除
呼叫後相關紀錄 mockFn.mock.calls
⬆️ mockFn.mock.instances
⬆️ mockFn.mock.contexts
模擬 function 行為 mockFn.mockImplementation()
⬆️ mockFn.mockReturnValue()
⬆️ mockFn.mockResolvedValue()
還原 function jest.fn()

 

mock.mockReset()

會覆寫掉 mock api 相關的紀錄,像是 呼叫的次數產生的實例數量 等,也會清除需要引入的 input 或輸出的 output 等條件,把 jest.fn 變成 undefined

主要目的 mock 值 是否被移除
呼叫後相關紀錄 mockFn.mock.calls
⬆️ mockFn.mock.instances
⬆️ mockFn.mock.contexts
模擬 function 行為 mockFn.mockImplementation()
⬆️ mockFn.mockReturnValue()
⬆️ mockFn.mockResolvedValue()
還原 function jest.fn()

 

mock.mockRestore()

會覆寫掉 mock api 相關的紀錄,像是 呼叫的次數產生的實例數量 等,也會清除需要引入的 input 或輸出的 output 等條件,甚至還原成原本的 function,不再是 jest.fn

主要目的 mock 值 是否被移除
呼叫後相關紀錄 mockFn.mock.calls
⬆️ mockFn.mock.instances
⬆️ mockFn.mock.contexts
模擬 function 行為 mockFn.mockImplementation()
⬆️ mockFn.mockReturnValue()
⬆️ mockFn.mockResolvedValue()
還原 function jest.fn()

 

注意:此函式在使用 jest.spyOn 下才可以使用,一般的 jest.fn() 無法使用此函式

 

實際使用

在我現在的開發經驗中,我們的情境只需要去清除 呼叫的相關紀錄,所以我們選用了 mock.mockClear 來作為 clear api 的紀錄,不用另外去清除 api response

以下為實際範例:

describe('ThirdPartySources', () => {
  beforeEach(() => {
    mockApiGetUsers.mockResolvedValue(defaultMockApiGetUsers);
  });

  afterEach(() => {
    mockApiGetUsers.mockClear();
  });

  test('when there is no azure, okta is in ad sources, should show refresh status button', async () => {
    // Act
    const { findByTestId } = renderWithRedux(<ThirdPartySources></ThirdPartySources>);
    const refreshBtn = await findByTestId(idBtnConnectionStatus);

    // Assert
    expect(refreshBtn).toBeVisible();
  });
});

 

今天小結

  • 知道清除 mock data 的重要性,是為了要保持每個單元測試獨立運作
  • 知道 jest 提供 3 個 util 幫助我們清理 mock data,以實務上來說 mock.mockClear() 最常用

 

參考資訊


上一篇
[Day 12] 測試思維 & 單元測試 - (8) 與 api 的測試
下一篇
[Day 14] 測試思維 & 單元測試 - (10) 測試 api 與 React Query 的最佳幫手 - MockServiceWorker
系列文
為了成為更好的前端,我開始在乎的那些事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言