npm install --save-dev jest
For TypeScript:
npm install --save-dev ts-jest @types/jest
npx ts-jest config:init
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
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);
});
});
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
expect(value).toBeGreaterThan(number);
expect(value).toBeGreaterThanOrEqual(number);
expect(value).toBeLessThan(number);
expect(value).toBeLessThanOrEqual(number);
expect(value).toBeCloseTo(number, precision);
expect(string).toMatch(/regex/);
expect(array).toContain(item);
expect(array).toHaveLength(number);
expect(object).toHaveProperty(keyPath, value);
expect(object).toHaveProperty('kitchen.area', 20);
expect(() => {
throw new Error('error');
}).toThrow('error');
async function to throw
it('should test async errors', async () => {
await expect(failingAsyncTest())
.rejects
.toThrow('I should fail');
});
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
expoect(mockFn).toHaveBeenCalledWith(...args);
expect(mockFn).toHaveBeenCalledTimes(1);
const mockFn = jest.fn().mockReturnValue(42);
expect(mockFn()).toBe(42);
const mockFn2 = jest.fn().mockImplementation((x) => x + 1);
expect(mockFn2(1)).toBe(2);
// Uses a custom implementation that adds 1
const mockFn3 = jest.fn()
.mockImplementation((x) => x + 1);
expect(mockFn3(1)).toBe(2);
expect(mockFn3(5)).toBe(6);
// Custom implementation only on the first call, then undefined
const mockFn4 = jest.fn()
.mockImplementationOnce((x) => x * 2);
expect(mockFn4(3)).toBe(6);
expect(mockFn4(3)).toBeUndefined();
const obj = {
method: (x) => x + 1,
};
const spy = jest.spyOn(obj, 'method');
obj.method(2);
expect(spy).toHaveBeenCalledWith(2);
// Always returns 42
const mockFn = jest.fn().mockReturnValue(42);
expect(mockFn()).toBe(42);
expect(mockFn()).toBe(42); // Still 42
// Returns 10 on the first call, then undefined afterward
const mockFn2 = jest.fn()
.mockReturnValueOnce(10);
expect(mockFn2()).toBe(10);
expect(mockFn2()).toBeUndefined();
// mockResolvedValue: always resolves to the given value
const fetchData = jest.fn().mockResolvedValue({ data: 'Mocked data' });
test('it resolves with mocked data', async () => {
const result = await fetchData();
expect(result).toEqual({ data: 'Mocked data' });
});
// mockResolvedValueOnce: resolves with different values on each call
const fetchData2 = jest.fn()
.mockResolvedValueOnce({ data: 'Mocked data #1' })
.mockResolvedValueOnce({ data: 'Mocked data #2' })
.mockResolvedValue({ data: 'Default mocked data' });
test('returns different values for sequential calls', async () => {
let result = await fetchData2();
expect(result).toEqual({ data: 'Mocked data #1' });
result = await fetchData2();
expect(result).toEqual({ data: 'Mocked data #2' });
result = await fetchData2();
expect(result).toEqual({ data: 'Default mocked data' });
});
// mockRejectedValue: always rejects with an error
const fetchData3 = jest.fn().mockRejectedValue(new Error('Async error'));
test('rejects with an error', async () => {
await expect(fetchData3()).rejects.toThrow('Async error');
});
// mockRejectedValueOnce: rejects on first call, resolves on subsequent calls
const fetchData4 = jest.fn()
.mockRejectedValueOnce(new Error('Async error #1'))
.mockResolvedValue({ data: 'Recovery data' });
test('rejects on first call, resolves on second', async () => {
await expect(fetchData4()).rejects.toThrow('Async error #1');
await expect(fetchData4()).resolves.toEqual({ data: 'Recovery data' });
});
// Chain multiple resolved/rejected calls
const someAsyncFunction = jest.fn()
.mockResolvedValueOnce('First call')
.mockRejectedValueOnce(new Error('Second call failed'))
.mockResolvedValue('All subsequent calls');
import { fetchUserData } from './dataService'; // The function you're mocking
jest.mock('./dataService', () => ({
fetchUserData: jest.fn()
}));
describe('test asynchronous data fetch', () => {
it('successfully fetches data', async () => {
fetchUserData.mockResolvedValue({ name: 'Alice', age: 25 });
const result = await fetchUserData();
expect(result).toEqual({ name: 'Alice', age: 25 });
expect(fetchUserData).toHaveBeenCalledTimes(1);
});
it('handles errors gracefully', async () => {
fetchUserData.mockRejectedValue(new Error('Network issue'));
try {
await fetchUserData();
throw new Error('This test should have failed but did not');
} catch (error) {
expect(error).toBeInstanceOf(Error);
expect(error.message).toBe('Network issue');
}
});
});
test('promise resolves', async () => {
await expect(Promise.resolve('value')).resolves.toBe('value');
});
test('async/await', async () => {
const data = await fetchData();
expect(data).toBe('value');
});
test('callback test', (done) => {
function callback(data) {
expect(data).toBe('value');
done();
}
asyncOperation(callback);
});
test('matches snapshot', () => {
const tree = render(<Component />);
expect(tree).toMatchSnapshot();
});
npx jest --updateSnapshot
jest.mock('module-name');
jest.mock('module-name', () => ({
functionName: jest.fn(),
}));
jest.clearAllMocks();
jest.resetAllMocks();
jest.restoreAllMocks();
jest.config.js
module.exports = {
testEnvironment: 'node', // or 'jsdom'
transform: {
'^.+\\.jsx?
#### TypeScript Configuration
Update `jest.config.js`:
```javascript
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
npx jest --coverage
module.exports = {
collectCoverage: true,
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
};
Run Jest with Node debugger:
node --inspect-brk ./node_modules/.bin/jest --runInBand
: 'babel-jest',
},
moduleNameMapper: {
'\.(css|less)
Update jest.config.js
:
{{CODE_BLOCK_36}}
{{CODE_BLOCK_37}}
{{CODE_BLOCK_38}}
Run Jest with Node debugger:
{{CODE_BLOCK_39}}
#### TypeScript Configuration
Update `jest.config.js`:
{{CODE_BLOCK_36}}
---
### **Coverage**
#### Collect Coverage
{{CODE_BLOCK_37}}
#### Exclude Files in Config
{{CODE_BLOCK_38}}
---
### **Debugging**
Run Jest with Node debugger:
{{CODE_BLOCK_39}}
---