mock함수

mock

test를 진행하기 위해서 많은 코들르 작성해야 할때 임시로 mock 함수를 사용해서 기능이 정상 작동하는지 확인할 수 있다.

calls

mock 안에 mock.calls 가 있어서 몇번 실행됬는지 인수는 무엇이였는지 확인 가능

1
2
3
4
5
6
7
8
9
10
11
12
13
const fn = require("./fn");

const mock = jest.fn();

mock();
mock(1);

test("mock 함수는 2번 호출되었다.", () => {
expect(mock.mock.calls.length).toBe(2);
});
test("2번째 호출의 인수는 1이다.", () => {
expect(mock.mock.calls[1][0]).toBe(1);
});

인수도 확인 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const fn = require("./fn");

const mock = jest.fn();

function addEachOne(arr) {
arr.forEach((num) => {
mock(num + 1);
});
}

addEachOne([10, 20, 30]);

test("mock 함수는 3번 불렸다.", () => {
expect(mock.mock.calls.length).toBe(3);
});
test("가 값은 11, 21, 31이다.", () => {
expect(mock.mock.calls[0][0]).toBe(11);
expect(mock.mock.calls[1][0]).toBe(21);
expect(mock.mock.calls[2][0]).toBe(31);
});

return

fn()에 콜백함수를 전달해서 result로 확인할 수 있다.

results 배열로 들어오고 value로 return 값 확인이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const fn = require("./fn");

const mock = jest.fn((num) => num + 1);

mock(10);
mock(20);
mock(30);

test("10에서 1증가한 11이 반환된다.", () => {
expect(mock.mock.results[0].value).toBe(11);
});
test("20에서 1증가한 21이 반환된다.", () => {
expect(mock.mock.results[1].value).toBe(21);
});
test("30에서 1증가한 31이 반환된다.", () => {
expect(mock.mock.results[2].value).toBe(31);
});

mockReturnValueOnce를 통해서 한번만 리턴하는 값을 정할 수 있다.

체이닝으로 연결하고 마지막은 mockReturnValue로 정한다.

홀수 판별을 위한 콜백을 당장 작성할수 없다 판단될때 다음과 같이 작성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const fn = require("./fn");

const mock = jest.fn((num) => num + 1);

mock
.mockReturnValueOnce(true)
.mockReturnValueOnce(false)
.mockReturnValueOnce(true)
.mockReturnValueOnce(false)
.mockReturnValue(true);

test("홀수는 135 이다.", () => {
const result = [1, 2, 3, 4, 5].filter((num) => mock(num));
expect(result).toStrictEqual([1, 3, 5]);
});

mockResolvedValue 를 통해서 비동기 함수를 흉내 낼 수 도 있다.

1
2
3
4
5
6
7
8
9
10
11
const fn = require("./fn");

const mock = jest.fn((num) => num + 1);

mock.mockResolvedValue({ name: "mike" });

test("이름은 mike이다", () => {
mock().then((res) => {
expect(res.name).toBe("mike");
});
});

기존 함수를 mock 함수로 만들기

유저 생성 함수를 test 한다고 생각할 때 실제로 user가 생성해 버리면 롤백하기도 번거로울 것이다.

1
2
3
4
5
6
createUser: (name) => {
console.log("실제로 유저가 생성되었다.");
return {
user: name
}
},

fn을 목킹 모드로 만든다. 이러면 실제 fn에 함수가 호출되는 것이 아니라 목함수가 동작한다.

1
2
3
4
5
6
7
8
9
10
const fn = require("./fn");

jest.mock("./fn");

fn.createUser.mockReturnValue({ user: "Mike" });

test("유저가 생성되었습니다.", () => {
const result = fn.createUser("Mike");
expect(result.user).toBe("Mike");
});

그 외에 유용한 메서드

mock 함수 호출에 대한 유용한 메서드를 제공한다.

  • toBeCalled() 한번이라도 호출됬으면 통과
  • toBeCalledTimes(3) 3번 통과 됬으면 통과
  • toBeCalledWith(10, 20) 인수로 주어진 것을 받은게 있다면 통과
  • lastCalledWith(10, 20) 마지막으로 받은 인수가 10, 20이면 통과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const fn = require("./fn");

const mock = jest.fn();

mock(10, 20);
mock();
mock(30, 40);

test("호출됨", () => {
expect(mock).toBeCalled();
});
test("3 번 호출됨", () => {
expect(mock).toBeCalledTimes(3);
});
test("10, 20 인수로 받음", () => {
expect(mock).toBeCalledWith(10, 20);
});
test("호출됨", () => {
expect(mock).lastCalledWith(30, 40);
});