0018.3 jest testing framework for Node.js
Cheatsheet#
Installation#
npm install --save-dev jest
For TypeScript:
npm install --save-dev ts-jest @types/jest
npx ts-jest config:init
Basic Commands#
- Run tests:
npx jest
- Watch mode:
npx jest --watch
- Run specific test file:
npx jest path/to/testFile.test.js
- Clear cache:
npx jest --clearCache
Test Structure#
describe('Group of tests', () => {
beforeAll(() => {
// Runs once before all tests
});
beforeEach(() => {
// Runs before each test
});
afterEach(() => {
// Runs after each test
});
afterAll(() => {
// Runs once after all tests
});
test('should do something', () => {
expect(true).toBe(true);
});
});
Matchers#
Common Matchers#
expect(value).toBe(value); // Strict equality
expect(value).toEqual(value); // Deep equality
expect(value).toEqual(expect.any(constructor)) // Matches anything that was created with the given constructor
expect(value).toBeNull(); // null
expect(value).toBeDefined(); // Not undefined
expect(value).toBeUndefined(); // undefined
expect(value).toBeTruthy(); // true-like
expect(value).toBeFalsy(); // false-like
Numbers#
expect(value).toBeGreaterThan(number);
expect(value).toBeGreaterThanOrEqual(number);
expect(value).toBeLessThan(number);
expect(value).toBeLessThanOrEqual(number);
expect(value).toBeCloseTo(number, precision);
Strings#
expect(string).toMatch(/regex/);
Arrays/Iterables#
expect(array).toContain(item);
Exceptions#
expect(() => {
throw new Error('error');
}).toThrow('error');
Mock Functions#
Basic Mock#
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
expoect(mockFn).toHaveBeenCalledWith(...args);
expect(mockFn).toHaveBeenCalledTimes(1);
Mock Implementation#
const mockFn = jest.fn().mockReturnValue(42);
expect(mockFn()).toBe(42);
const mockFn2 = jest.fn().mockImplementation((x) => x + 1);
expect(mockFn2(1)).toBe(2);
Spy on Existing Function#
const obj = {
method: (x) => x + 1,
};
const spy = jest.spyOn(obj, 'method');
obj.method(2);
expect(spy).toHaveBeenCalledWith(2);
Async Testing#
Testing Promises#
test('promise resolves', async () => {
await expect(Promise.resolve('value')).resolves.toBe('value');
});
Testing Async/Await#
test('async/await', async () => {
const data = await fetchData();
expect(data).toBe('value');
});
Testing Callbacks#
test('callback test', (done) => {
function callback(data) {
expect(data).toBe('value');
done();
}
asyncOperation(callback);
});
Snapshots#
Creating Snapshots#
test('matches snapshot', () => {
const tree = render(<Component />);
expect(tree).toMatchSnapshot();
});
Updating Snapshots#
npx jest --updateSnapshot
Mock Modules#
Mock Entire Module#
jest.mock('module-name');
Mock Specific Function#
jest.mock('module-name', () => ({
functionName: jest.fn(),
}));
Clear/Reset Mocks#
jest.clearAllMocks();
jest.resetAllMocks();
jest.restoreAllMocks();
Configuring Jest#
jest.config.js
#
module.exports = {
testEnvironment: 'node', // or 'jsdom'
transform: {
'^.+\\.jsx?$': 'babel-jest',
},
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
},
};
TypeScript Configuration#
Update jest.config.js
:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
Coverage#
Collect Coverage#
npx jest --coverage
Exclude Files in Config#
module.exports = {
collectCoverage: true,
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
};
Debugging#
Run Jest with Node debugger:
node --inspect-brk ./node_modules/.bin/jest --runInBand