Jest 繞過模塊模擬

2021-09-18 20:27 更新

Jest 允許在測試中模擬整個模塊,這對于測試你的代碼是否正確地從該模塊調用函數非常有用。但是,有時你可能希望在測試文件中使用部分模擬模塊,在這種情況下,希望訪問原始實現(xiàn),而不是模擬版本。

考慮為此?createUser?函數編寫一個測試用例:

  1. // createUser.js
  2. import fetch from 'node-fetch';
  3. export const createUser = async () => {
  4. const response = await fetch('http://website.com/users', {method: 'POST'});
  5. const userId = await response.text();
  6. return userId;
  7. };

你的測試將要模擬?fetch?函數,以便我們可以確保在不實際發(fā)出網絡請求的情況下調用它。但是,還需要模擬?使用 ?Response?(包裝在?Promise?中)模擬fetch?的返回值,因為我們的函數使用它來獲取創(chuàng)建的用戶 ID。因此,你最初可能會嘗試編寫這樣的測試:

  1. jest.mock('node-fetch');
  2. import fetch, {Response} from 'node-fetch';
  3. import {createUser} from './createUser';
  4. test('createUser calls fetch with the right args and returns the user id', async () => {
  5. fetch.mockReturnValue(Promise.resolve(new Response('4')));
  6. const userId = await createUser();
  7. expect(fetch).toHaveBeenCalledTimes(1);
  8. expect(fetch).toHaveBeenCalledWith('http://website.com/users', {
  9. method: 'POST',
  10. });
  11. expect(userId).toBe('4');
  12. });

但是,如果運行該測試,你會發(fā)現(xiàn)該?createUser?函數會失敗,并拋出錯誤:?TypeError: response.text is not a function?。這是因為?Response從中導入的類?node-fetch?已被模擬(由于?jest.mock?測試文件頂部的調用),因此它不再按應有的方式運行。

為了解決此類問題,Jest 提供了?jest.requireActual?幫助程序。要使上述測試工作,請對測試文件中的導入進行以下更改:

  1. // BEFORE
  2. jest.mock('node-fetch');
  3. import fetch, {Response} from 'node-fetch';
  1. // AFTER
  2. jest.mock('node-fetch');
  3. import fetch from 'node-fetch';
  4. const {Response} = jest.requireActual('node-fetch');

這允許你的測試文件從node-fetch?導入實際?Response?對象?,而不是模擬版本。這意味著測試現(xiàn)在將正確通過。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號