外部Library的mock方法

import { function1, function2 } from 'library';

jest.mock('library', () => {
  return {
    function1: jest.fn(),
    function2: jest.fn(),
  };
});

官網有列出下列方法: (關於mock會提升到最前面官網的解釋在這裡)

jest.mock('node-fetch'); // 這裡是因為jest會把mock提升到最前面執行

import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';

// jest.mock('node-fetch'); <-原本應該是在這邊

test('createUser calls fetch with the right args and returns the user id', async () => {
  fetch.mockReturnValue(Promise.resolve(new Response('4'))); // fetch是class

  const userId = await createUser();

  expect(fetch).toHaveBeenCalledTimes(1);
  expect(fetch).toHaveBeenCalledWith('https://website.com/users', {
    method: 'POST',
  });
  expect(userId).toBe('4');
});

但我實測必須是class才能直接mock後執行.mockReturnValue()或.mockImplementation(),不然會出現library._default.mockImplementation is not a functionerror。所以推測fetch應該是以class export出來的class。

只Mock package內特定某個函數

可以使用jest.requireActual,讓該package其他函數依照原本的方式運作。 開始測試之後可以使用jest.mockImplementationOnce()或是jest.mockImplementation()去更改mock的方法

import { useMatch } from 'react-router-dom';

// 下面這個jest.mock()執行時,會被提升到最前面
jest.mock('react-router-dom', () => {
  return {
    ...jest.requireActual('react-router-dom'),
    useMatch: jest.fn(() => null),
  };
});

describe('<Component />', () => {
  it('should be status 1', () => {
    render(<Component />);
    // 此時component內的useMatch()會回傳null (依照上面定義)
  });

  it('should be status 2', () => {
    useMatch.mockImplementationOnce(() => true);
    render(<Component />);
    // 此時component內的useMatch()會回傳true
  });
});

這樣就可以測試Component在route match時的狀態了。

reset processes

清除所有mock被call的次數

beforeEach(() => {
  jest.clearAllMocks();
});
// or clear single mock funtion
mockFunction.mockClear()

Sample

redux slice (with default export reducer & export actions)

jest.mock('../slice', () => {
  const reducers = jest.requireActual('../slice');

  return {
    __esModule: true,
    ...reducers,
    actionOne: jest.fn(),
  };
});

Intellisense Setting

有幾個方法能讓VSCode在以下檔案類別*.spec.js(x)?, *.test.js(x)?能提供jest intellisense

  • 安裝 @testing-library/jest-dom
yarn add -D @testing-library/jest-dom
  • 安裝 @types/jest
yarn add -D @types/jest