toBe
는 값과 타입이 동일한지 모두 검사, 객체나 배열의 참조값까지 비교, toEqual
은 값만을 비교하며, 객체나 배열 내부의 값이 동일한지 검사toEqual
recursively checks every field of an object or array.test('object assignment', () => {
const data = {one: 1};
data['two'] = 2;
expect(data).toEqual({one: 1, two: 2});
});
아래와 같은 matcher들이 존재한다.
toBeNull
toBeUndefined
toBeDefined
toBeTruthy
toBeFalsy
아래와 같은 matcher들이 존재한다.
toBeGreaterThan
toBeGreaterThanOrEqual
toBeLessThan
toBeLessThanOrEqual
toBeCloseTo
를 활용객체나 set과 같은 이터러블에 대하여 toContain
matcher를 활용할 수 있다.
특정 함수가 에러를 반환하는지 아닌지를 테스트하기 위해서는 toThrow
를 활용한다.
toThrow
의 인자로 에러를 전달할 수도, 에러 메시지를 전달할 수도 있다.
이외의 수많은 Matcher는 여기서 확인할 수 있다.
test('the data is peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
test('the data is peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
await fetchData();
} catch (e) {
expect(e).toMatch('error');
}
});
아래와 같이 작성해줄 수도 있다.
test('the data is peanut butter', async () => {
await expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
await expect(fetchData()).rejects.toMatch('error');
});
비동기 코드를 테스트할 때는 assetions를 써주는 게 좋다.
비동기로 테스트를 진행할 때에는 어떤 expect문이 먼저 실행될지, 그 순서를 보장받을 수 없으므로, test에게 몇개의 expect문이 포함될지를 미리 알려주는 절차라고 이해하면 쉽다.
test('doAsync calls both callbacks', () => {
expect.assertions(2);
function callback1(data) {
expect(data).toBeTruthy();
}
function callback2(data) {
expect(data).toBeTruthy();
}
doAsync(callback1, callback2);
});
beforeEach
afterEach
beforeAll
afterAll
beforeEach and afterEach can handle asynchronous code in the same ways that tests can handle asynchronous code - they can either take a done parameter or return a promise. For example, if initializeCityDatabase() returned a promise that resolved when the database was initialized, we would want to return that promise:
Top-level에 있는 beforeEach는 특정 describe 스코프 안에 있는 beforeEach보다 앞서 실행된다.
beforeAll(() => console.log('1 - beforeAll'));
afterAll(() => console.log('1 - afterAll'));
beforeEach(() => console.log('1 - beforeEach'));
afterEach(() => console.log('1 - afterEach'));
test('', () => console.log('1 - test'));
describe('Scoped / Nested block', () => {
beforeAll(() => console.log('2 - beforeAll'));
afterAll(() => console.log('2 - afterAll'));
beforeEach(() => console.log('2 - beforeEach'));
afterEach(() => console.log('2 - afterEach'));
test('', () => console.log('2 - test'));
});
// 1 - beforeAll
// 1 - beforeEach
// 1 - test
// 1 - afterEach
// 2 - beforeAll
// 1 - beforeEach
// 2 - beforeEach
// 2 - test
// 2 - afterEach
// 1 - afterEach
// 2 - afterAll
// 1 - afterAll
before*
및 after*
핸들러 내에서 설정 및 해체 작업을 수행하는 것이 더 좋은 이유 중 하나before*
과 after*
는 작성된 순서대로 실행된다. const mockCallback = jest.fn(x => 42 + x);
라고 할 때mockCallback.mock.calls
: 목 함수가 호출될 때 전달인자를 담은 정보mockCallback.mock.results
: 목 함수가 반환한 결과를 담은 정보.mock
속성은 각 콜의 this
를 추적한다. const myMock1 = jest.fn();
const a = new myMock1();
console.log(myMock1.mock.instances);
// > [ <a> ]
const myMock2 = jest.fn();
const b = {};
const bound = myMock2.bind(b);
bound();
console.log(myMock2.mock.contexts);
// > [ <b> ]
// The function was called with a certain `this` context: the `element` object.
expect(someMockFunction.mock.contexts[0]).toBe(element);
// This function was instantiated exactly twice
expect(someMockFunction.mock.instances.length).toBe(2);
// The object returned by the first instantiation of this function
// had a `name` property whose value was set to 'test'
expect(someMockFunction.mock.instances[0].name).toBe('test');
// The first argument of the last call to the function was 'test'
expect(someMockFunction.mock.lastCall[0]).toBe('test');
.mockReturnValueOnce
mockResolvedValue
import axios from 'axios';
import Users from './users';
jest.mock('axios');
test('should fetch users', () => {
const users = [{name: 'Bob'}];
const resp = {data: users};
axios.get.mockResolvedValue(resp);
// or you could use the following depending on your use case:
// axios.get.mockImplementation(() => Promise.resolve(resp))
return Users.all().then(data => expect(data).toEqual(users));
});
.requireActual
jest.mock('../foo-bar-baz', () => {
const originalModule = jest.requireActual('../foo-bar-baz');
//Mock the default export and named export 'foo'
return {
__esModule: true,
...originalModule,
default: jest.fn(() => 'mocked baz'),
foo: 'mocked foo',
};
});
mockImplementation
mockImplementationOnce
도 존재jest.mock('../foo'); // this happens automatically with automocking
const foo = require('../foo');
// foo is a mock function
foo.mockImplementation(() => 42);
foo();
// > 42
.mockReturnThis
도 존재. this를 return하는 내부 구현을 모킹하는 함수 const mockAdd = jest.fn().mockName('바보');
jest.mock('./math', () => ({
add: mockAdd
}));
test('add function', () => {
mockAdd.mockReturnValue(10);
const result = math.add(3, 5);
expect(mockAdd).toHaveBeenCalledWith(3, 5);
expect(result).toBe(10);
});
// The mock function was called at least once
expect(mockFunc).toHaveBeenCalled();
// The mock function was called at least once with the specified args
expect(mockFunc).toHaveBeenCalledWith(arg1, arg2);
// The last call to the mock function was called with the specified args
expect(mockFunc).toHaveBeenLastCalledWith(arg1, arg2);
// All calls and the name of the mock is written as a snapshot
expect(mockFunc).toMatchSnapshot();