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.tsx
Run 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);
});