forEach
를 직접 구현한다고 가정해보자.function forEach(items, callback) {
for (let index=0; index < items.length; index++){
callback(items[index])
}
}
위의 함수를 테스트하기 위해, mock function을 사용 할 수 있다.
const mockCallback = jest.fn(x => 42+x);
forEach([0,1], mockCallback);
// mock function은 2번 호출 된다.
expect(mockCallback.mock.calls.length).toBe(2);
// 처음 호출 되는 함수의 첫번째 요소는 0이다.
expect(mockCallback.mock.calls[0][0]).toBe(0);
// 두번째로 호출 되는 함수의 첫번째 요소는 1이다.
expect(mockCallback.mock.calls[1][0]).toBe(1);
// 처음 호출 되는 함수의 결과 값은 42이다.
expect(mockCallback.mock.results[0].value).toBe(42);
.mock
property.mock
property를 가지고 있다..mock
property는 mock 함수가 어떻게 호출 되었는지, 어떤 값을 return 하는지 등의 정보를 가지고 있다..mock
property는 매 호출 시 this
값도 가지고 있다. const myMock1 = jest.fn();
const a = new myMock1();
console.log(myMock1.mock.instances);
const myMock2 = jest.fn();
const b = {};
const bound = myMock2.bind(b);
bound();
console.log(myMock2.mock.contexts);
const mymock = jest.fn();
console.log(myMock());
// undefined
myMock.mockReturnValueOnce(10).mockReturnValueOnce('x').mockReturnValue(true);
console.log(myMock(), myMock(), myMock(), myMock());
// 10, 'x', true, true
const filterTestFn = jset.fn();
filterTestFn.mockReturnValueOnce(true).mockReturnValueOnce(false);
const result = [11,12].filter(num => filterTestFn(num));
console.log(result);
// [11]
console.log(filterTestFn.mock.calls[0][0]); // 11
console.log(filterTestFn.mock.calls[1][0]); // 12
jest.mock(...)
기능을 사용해보자// users.js
// 실제 구현된 API 호출 모듈
import axios from 'axios';
class Users {
static all() {
return axios.get('/user.json').then(resp => resp.data);
}
}
export default Users;
// users.test.js
// mock 으로 구현된 모듈을 이용한 테스트
import axios from 'axios'
import Users from './users'
jest.mock('axios');
test('should fetch users', () => {
const users = [{name:'Bob'}];
const res = {data:users};
axios.get.mockResolvedValue(res);
return Users.all().then(data => expect(data).toEqual(users));
// or
const result = await Users.all();
expect(result).toEqual(users);
});
//foo-bar-baz.js
export const foo = 'foo';
export const bar = () => 'bar';
export default () => 'baz';
//test.js
import defaultExport, {bar,foo} from '../foo-bar-baz';
jest.mock('../foo-bar-baz', () =>{
const originalModule = jest.requireActual('../foo-bar-baz');
return {
__esModule: true,
...originalModuel,
default : jest.fn(() => 'mocked baz')
foo: 'mocked foo',
};
});
test('should do a partial mock', () => {
const defaultExportResult = defaultExport();
expect(defaultExportResult).toBe('mocked baz');
expect(defaultExport).toHaveBeenCalled();
// tohaveBeenCalled() : mock function 이 최소 한번은 호출 되었는지 확인 하는것.
expect(foo).toBe('mocked foo');
expect(bar()).toBe('bar');
});
jest.fn
, mockImplementation
을 사용 하여 구현 가능하다.const mockFn = jest.fn(cb => cb(null,true));
mockFn((err,val) => console.log(val));
// true
mockImplementation
은 다른 모듈에서 생긴 mock function을 정의 할때 유용하다.// foo.js
module.exports = function(){
//...
};
// test.js
jest.mock('../foo'):
const foo = require('../foo');
// foo is mock function
foo.mockImplementation(() => 42);
foo();
// 42
mockimplementationOnce
를 사용하는것이 유용하다.const myMockfn = jest.fn().mockImplementationOnce(cb => cb(null,true)).mockImplementationOnce(cb => cb(null, false));
myMockFn((err,val) => console.log(val));
// true
myMockFn((err,val) => console.log(val));
// false
mockImplementationOnce
로 정의한 수보다 더 많이 mock function을 실행 시키면, jest.fn
으로 설정된 기본 값이 출력 된다.const myMockFn = jest
.fn(() => 'default')
.mockImplementationOnce(() => 'first call')
.mockImplementationOnce(() => 'second call');
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
// > 'first call', 'second call', 'default', 'default'
.mockReturnThis()
를 사용 할수 있다.const myObj = {
myMethod: jest.fn().mockReturnThis(),
};
// 아래와 같다.
const otherObj = {
myMethod: jest.fn(function () {
return this;
}),
};
test('test dispaly mock fucntion name', () => {
const myMock = jest.fn().mockName('nameMock')
//myMock();
expect(myMock).toHaveBeenCalled();
});
// 이름 지정한 경우 expect(nameMock).toHaveBeenCalled()
// 이름 지정 안한 경우 expect(jest.fn()).toHaveBeenCalled()
.mock
property를 통해 직접 구현이 가능.
//mock function 이 최소 1번은 호출 됨
expect(mockFunc).toHaveBeenCalled();
expect(mockFunc.mock.calls.length).toBeGreaterThan(0);
// mock function이 최소 한번은 arg요소들과 호출 됨
expect(mockFunc).toHaveBeenCalledWith(arg1, arg2);
expect(mockFunc.mock.calls).toContainEqual([arg1, arg2]);
// 마지막으로 호출된 mock Function이 특정 arg 요소들과 함게 호출됨
expect(mockFunc).toHaveBeenLastCalledWith(arg1, arg2);
expect(mockFunc.mock.calls[mockFunc.mock.calls.length - 1]).toEqual([
arg1,
arg2,
]);
// 모든 호출과 mock의 이름이 snapshot에 쓰여진과 같음
expect(mockFunc).toMatchSnapshot();
expect(mockFunc.mock.calls).toEqual([[arg1, arg2]]);
expect(mockFunc.getMockName()).toBe('a mock name');
references : https://jestjs.io/docs/mock-functions