Jest
Command line
Given this configuration in package.json:
{
"scripts": {
"test": "jest"
}
}For the full documentation, check Jest CLI Options.
Run a specific script with:
pnpm run test __tests__/path/to/test.tsxRun a specific test with (match against the name in describe or test):
pnpm run test -t 'open home screen'Parametrize
Check the full documentation here.
Using a list:
test.each([
[1, 'expected output 1'],
[2, 'expected output 2'],
])('test with param %i', (inputNum, expected) => {
console.log(`${inputNum} ${expected}`);
})Using a dict:
test.each([
{ inputNum: 1, expected: 'expected output 1' },
{ inputNum: 2, expected: 'expected output 2' },
])('test with param $inputNum', ({ inputNum, expected }) => {
console.log(`${inputNum} ${expected}`);
})Expect error
If a call is expected to throw an error:
expect(() => willThrow()).toThrow();The code changes slightly if we are doing things asynchronously:
await expect(() => asyncWillThrow()).rejects.toThrow();Mocking
List of functions here.
| Function | Description |
|---|---|
mockClear | Clean up a mocks usage data between two assertions. |
mockReset | Replaces the mock implementation with an empty function. |
mockRestore | Restores the original (non-mocked) implementation. |
Mock import
Example of mocking import { useRouter } from 'next/router'.
To mock the same value for all tests:
jest.mock('next/router', () => ({
useRouter() {
return {
pathname: '/home',
};
},
}));To mock different values for each test:
import { useRouter } from 'next/router';
jest.mock('next/router', () => ({
useRouter: jest.fn(),
}));
describe('MyTest', () => {
test('tests something', () => {
(useRouter as jest.Mock).mockReturnValue({
pathname: '/home',
});
});
});To mock axios (reference):
Import:
import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;Without delay:
mockedAxios.get.mockResolvedValue({data: []});With delay:
mockedAxios.get.mockImplementation(() => {
return new Promise((resolve) => {
setTimeout(() => resolve({data: []}), 50);
});
});Mock builtin
Mocking window (reference):
Suppose you have window.open('http://example.com', '_blank').focus(). You can use jest.spyOn to mock window.
let windowOpenSpy: jest.Mock;
let windowOpenFocusMock: jest.Mock;
beforeEach(() => {
windowOpenSpy = jest.spyOn(window, 'open') as jest.Mock;
windowOpenFocusMock = jest.fn(() => {});
windowOpenSpy.mockReturnValue({
focus: windowOpenFocusMock,
});
});
afterEach(() => {
windowOpenFocusMock.mockRestore();
windowOpenSpy.mockRestore();
});Then inside the test:
await act(async () => {
fireEvent.click(screen.getAllByRole('button', { name: 'Open new window' }));
});
expect(windowOpenSpy).toHaveBeenCalledWith('http://example.com', '_blank');
expect(windowOpenFocusMock).toHaveBeenCalled();Mocking global:
Some (all?) global variables are not defined inside jest.
global.URL.createObjectURL = jest.fn(() => '');
global.URL.revokeObjectURL = jest.fn();Mocking console:
Validate logs and (optionally) prevent them from polluting test logs.
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); // Skip mockImplementation to keep logs
functionToBeTested();
expect(consoleWarnSpy).toHaveBeenCalledWith('something was not quite as expected');Mock timers
Mocking setTimeout-like native functions (reference):
jest.useFakeTimers();
test('my test', () => {
// ...
jest.runAllTimers();
jest.runOnlyPendingTimers();
jest.advanceTimersByTime(1000);
});