본문으로 바로가기

[테스트 코드 - Jest] mock 함수

category 기타 (+ Legacy)/Legacy 2022. 3. 9. 07:25

[Jest] mock 함수

이번 게시글에서는 mock 함수와 같이 사용할 수 있는 matchers에 대해 간단하게 알아보겠습니다.

mock 함수

mock : 모조품, mock은 모조품이라는 뜻을 가지고 있습니다. 즉 진짜가 아닌 가짜테스트를 위해 함수, 데이터 등을 만들어서 사용하는 것입니다. 한번 알아보도록 하겠습니다.

mock 함수를 만드는 방법은 간단합니다. 아래 코드 1줄이면 됩니다.

const mockFn = jest.fn();

위 함수로 무엇을 할 수 있을까요? 아래 코드는 짝수인지 홀수인지 검사하는 함수입니다. 한번 테스트 해보겠습니다.

// isEvenOdd 함수
function isEvenOdd(number, onResult) {
  if (number % 2) onResult("even");
  else onResult("odd");
}

// isEvenOdd 함수 test code
const isEvenOdd = require("../evenOdd");
const onResult = jest.fn();

it("isEvenOdd mock function test code", () => {
  isEvenOdd(3, onResult);
  isEvenOdd(4, onResult);

  console.log("# calls", onResult.mock.calls);
  expect(onResult.mock.calls.length).toBe(2);
  expect(onResult.mock.calls[0][0]).toBe("odd");
  expect(onResult.mock.calls[1][0]).toBe("even");
});
 

위 결과 이미지를 보면 onResult.mock.calls배열이 담겨져 있습니다. 배열 데이터를 보면 크기가 2인 것이 볼 수 있는데 이것은 mock 함수가 2번 호출되었기 때문입니다. 그리고 각각의 index에 odd, even이 있는 것을 확인할 수 있는 데 이것은 해당 mock 함수의 인자 값입니다. 이것을 확인하기 위해 expect로 calls.length = 2 즉, 총 호출 수는 2번, 1번째 결과는 odd, 2번째 결과는 even을 확인할 수 있습니다. 그런데 onResult.mock.calls~~ 를 외우기 힘들겠죠? 이러한 경우 아래처럼 간단하게 작성할 수도 있습니다.

it("isEvenOdd mock function test code - simple", () => {
  isEvenOdd(3, onResult);
  isEvenOdd(4, onResult);

  expect(onResult).toHaveBeenCalledTimes(2);
  expect(onResult).toHaveBeenCalledWith("odd");
  expect(onResult).toHaveBeenCalledWith("even");
  expect(onResult).toHaveBeenLastCalledWith("even");
  expect(onResult).toHaveBeenLastCalledWith("odd");
});

toHaveBeenCalledTimes로 총 호출 횟수, toHaveBeenCalledWith로 인자 값 테스트가 가능합니다. 마지막으로 toHaveBeenLastCalledWith matchers를 추가해보았는데요. 해당 matchers는 마지막 인자의 값을 테스트 하는 것입니다. 즉, even이 나와야 하는데 odd가 포함되어 있으면 테스트가 실패하게 됩니다. 아래 결과 이미지를 확인해봅시다.

mock 함수로 숫자 배열을 넘기면 짝수만 filter 해주는 함수를 만들어봅시다. mockReturnValueOnce, mockReturnValue를 이용하면 됩니다. 아래 코드를 참고해봅시다.

const mockFn = jest.fn();

mockFn
  .mockReturnValueOnce(10)
  .mockReturnValueOnce("x")
  .mockReturnValueOnce(false)
  .mockReturnValue(true);

test("test", () => {
  console.log(mockFn(), mockFn(), mockFn(), mockFn());
  expect(mockFn).toHaveBeenCalledTimes(4);
});

임의의 값을 반환해주는 함수를 만들기 위해서는 끝이 아닌 시점까지 mockReturnVlaueOnce, 마지막인 경우 mockReturnValue matcher를 사용하면 됩니다. 위 mock 함수는 순서대로 10, x, false, true 의 결과를 줍니다. 따라서 테스트를 진행하면 결과 값으로 10, x, false, true 가 표시됩니다. 그리고 호출도 4번 하였으니 test는 정상적으로 통과됩니다.

비동기 처리도 가능합니다. 예를들어 로그인 후 user 정보를 가져온다고 해봅시다. 테스트 코드는 아래와 같이 작성할 수 있습니다.

const getUserMockFn = jest.fn();

getUserMockFn.mockResolvedValue({ name: "홍길동", age: 15 });

test("name : 홍길동, age : 15", () => {
  getUserMockFn().then(res =>
    expect(res).toStrictEqual({ name: "홍길동", age: 15 })
  );
});

결과는 아래와 같습니다.

이번 게시글에서는 mock 함수에 대해 간단하게 알아보았습니다. 그리고 몇 개의 matchers를 이용하여 사용하는 방법을 알아보았습니다.

참고자료

마지막

해당 내용은 틀릴 수도 있습니다. 틀린 내용이 있으면 조언 부탁드립니다.

반응형