npm install --save-dev jest | Jest 설치 |
npx jest | 모든 테스트 실행 |
npx jest --watch | 감시 모드 |
npx jest --coverage | 커버리지 포함 |
npx jest path/to/test.js | 특정 파일 실행 |
npx jest -t "test name" | 매칭되는 테스트 실행 |
npx jest --verbose | 상세 출력 |
npx jest --updateSnapshot | 스냅샷 업데이트 |
test('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
}); it('should add numbers', () => {
expect(add(1, 2)).toBe(3);
}); describe('Calculator', () => {
describe('add', () => {
it('adds two numbers', () => {
expect(add(1, 2)).toBe(3);
});
});
}); test.skip('skipped test', () => {});
xtest('also skipped', () => {}); test.only('only this runs', () => {});
fit('also only this', () => {}); expect(value).toBe(expected); expect(obj).toEqual({ a: 1, b: 2 }); expect(value).not.toBe(expected); expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeNull();
expect(value).toBeUndefined();
expect(value).toBeDefined(); expect(value).toBeGreaterThan(3);
expect(value).toBeGreaterThanOrEqual(3);
expect(value).toBeLessThan(5);
expect(value).toBeLessThanOrEqual(5);
expect(0.1 + 0.2).toBeCloseTo(0.3); expect('hello world').toMatch(/world/);
expect(str).toContain('substring'); expect([1, 2, 3]).toContain(2);
expect([{a: 1}, {b: 2}]).toContainEqual({a: 1}); expect([1, 2, 3]).toHaveLength(3); expect(obj).toHaveProperty('name');
expect(obj).toHaveProperty('user.name', 'John'); expect(() => {
throw new Error('error');
}).toThrow();
expect(() => fn()).toThrow('specific message');
expect(() => fn()).toThrow(Error); await expect(asyncFn()).rejects.toThrow(); test('async test', async () => {
const data = await fetchData();
expect(data).toBe('data');
}); test('promise test', () => {
return fetchData().then(data => {
expect(data).toBe('data');
});
}); test('resolves', async () => {
await expect(fetchData()).resolves.toBe('data');
});
test('rejects', async () => {
await expect(fetchBadData()).rejects.toThrow();
}); test('callback test', done => {
fetchData(data => {
expect(data).toBe('data');
done();
});
}); const mockFn = jest.fn();
mockFn('arg1', 'arg2');
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');
expect(mockFn).toHaveBeenCalledTimes(1); const mockFn = jest.fn()
.mockReturnValue('default')
.mockReturnValueOnce('first')
.mockReturnValueOnce('second'); const mockFn = jest.fn()
.mockImplementation(x => x * 2); const mockFn = jest.fn()
.mockResolvedValue('data')
.mockResolvedValueOnce('first');
// Or
.mockRejectedValue(new Error('error')); jest.mock('./module');
import { fetchData } from './module';
fetchData.mockResolvedValue('mocked data'); jest.mock('./module', () => ({
...jest.requireActual('./module'),
fetchData: jest.fn()
})); jest.mock('axios');
import axios from 'axios';
axios.get.mockResolvedValue({ data: 'mocked' }); beforeEach(() => {
jest.clearAllMocks(); // Clear calls
jest.resetAllMocks(); // Reset implementations
jest.restoreAllMocks(); // Restore original
}); const spy = jest.spyOn(object, 'method');
object.method();
expect(spy).toHaveBeenCalled();
spy.mockRestore(); const spy = jest.spyOn(console, 'log')
.mockImplementation(() => {}); beforeAll(() => {
// Runs once before all tests
});
afterAll(() => {
// Runs once after all tests
}); beforeEach(() => {
// Runs before each test
});
afterEach(() => {
// Runs after each test
}); describe('group', () => {
beforeEach(() => {
// Only for tests in this describe
});
test('test 1', () => {});
test('test 2', () => {});
}); test('matches snapshot', () => {
const component = render(<Button />);
expect(component).toMatchSnapshot();
}); test('inline snapshot', () => {
expect(getData()).toMatchInlineSnapshot(`
Object {
"name": "John",
}
`);
}); expect(user).toMatchSnapshot({
createdAt: expect.any(Date),
id: expect.any(Number)
}); jest.useFakeTimers();
test('timer test', () => {
const callback = jest.fn();
setTimeout(callback, 1000);
jest.advanceTimersByTime(1000);
expect(callback).toHaveBeenCalled();
}); jest.runAllTimers();
jest.runOnlyPendingTimers(); afterEach(() => {
jest.useRealTimers();
}); module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/*.test.js'],
collectCoverage: true,
coverageDirectory: 'coverage',
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80
}
}
}; module.exports = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
globalSetup: '<rootDir>/globalSetup.js',
globalTeardown: '<rootDir>/globalTeardown.js'
}; module.exports = {
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
'\\.(css|scss)$': 'identity-obj-proxy'
}
};