본문 바로가기
Testing/Jest

Jest: Mock Function에 대해서

by 코딩쥐 2024. 9. 11.

Mock function, 한국말로 하면 '모의 함수'라고 한다. 이 모의 함수의 경우 테스트하고자 하는 코드가 사용해야 하는 function이나 class가 있을 경우, 이에 대한 가상의 함수를 만들어 테스트를 하는 것을 말한다. 테스트 작성을 위한 환경 구축이 어렵거나, 테스트 시간이 오래 걸리는 등의 경우에 사용한다. Mock function의 경우 불확실한 정보를 가지고 테스트를 시행하는 것이기 때문에, 실제 구현에 대한 테스트가 필요하다면 가능한 한 Mocking을 피하고 실제 코드를 테스트하는 것이 좋다. 

 

Mock function 사용하기 

1. Mock 함수 생성

가상의 함수를 생성하여 인자를 넘겨받아 호출할 수 있다. 

  • jest.fn();
test("3을 입력할 경우 값은 5가 나온다.", () => {
  // 입력값에 2를 더하는 모의함수를 생성함
  const mockfn = jest.fn(x => x+2);
  // 모의 함수에 대한 테스트 시행
  expect(mockfn(3)).toBe(5);
})

 

모든 mock function은 .mock이라는 프로퍼티를 가지고 있고, 받은 인자들을 배열 형태로 기억하고 있다. .mock.calls를 통해서 호출 인자를 로그에 출력하면 배열 형태로 기억하고 있는 것을 볼 수 있다.

const mockfn = jest.fn(x => x + 2);
mockfn(2);
mockfn(5);
mockfn("코딩쥐", "codingji");

describe("Mock function 호출된 인자를 확인한다.", () => {
  console.log(mockfn.mock.calls); // 모든 호출 인자를 로그에 출력합니다.

  test("mockfn 배열 길이가 3이다(호출된 횟수)", 
    () => expect(mockfn.mock.calls.length).toBe(3));

  test("mockfn이 호출된 횟수가 3이다.", 
    () => expect(mockfn).toHaveBeenCalledTimes(3));

  test("mockfn이 2로 호출되었다.", 
    () => expect(mockfn).toHaveBeenCalledWith(2));

  test("mockfn이 `코딩쥐`, `codingji`로 호출되었다", 
    () => expect(mockfn).toHaveBeenCalledWith("코딩쥐", "codingji"));

  test("mockfn이 호출 시 3번째 매개변수가 5다.",
    () => expect(mockfn.mock.calls[2][0]).toBe("코딩쥐")); // 올바른 인덱스 접근
});

 

2. Manual Mock 작성

(1) 원본 모듈을 작성한다. (math.js)

// math.js

const add = (a, b) => a + b;
const subtract = (a, b) => a - b;
const divide = (a, b) => a / b;
const multiply = (a, b) => a * b;

module.exports = { add, subtract, divide, multiply };

 

(2) __mocks__라는 폴더를 생성한다.

 

(3) __mocks__ 폴더 안에 원본 모듈과 같은 이름의 mock module로 사용할 파일을 작성한다. ( __mocks__/math.js)

* mock module이란 모듈 내부의 특정 메소드의 동작을 mock function으로 만들어 사용하는 방식

// __mocks__/math.js

const add = jest.fn((a, b) => a + b);
const subtract = jest.fn((a, b) => a - b);
const divide = jest.fn((a, b) => a / b);
const multiply = jest.fn((a, b) => a * b);

module.exports = { add, subtract, divide, multiply };

 

(3) 테스트 파일을 작성한다. 

  • jest.mock("mocking할 JS파일 위치");

해당 테스트 파일의 경로는 원본 모듈인 math.js의 경로이다. Jest가 자동으로 __mocks__ 폴더 안에 있는 mock function을 사용한다.

// fn.test.js
const math = require('../math');

jest.mock('../math'); // math.js 모듈을 모킹

describe("Manual Mock 테스트", () => {
  test("1과 2를 더하면 3이 된다.", () => {
    expect(math.add(1,2)).toBe(3);
  });

  test("5와 3을 빼면 2가 된다.", () => {
    expect(math.subtract(5,3)).toBe(2);
  });

  test("10을 2로 나누면 5가 된다.", () => {
    expect(math.divide(10,2)).toBe(5);
  });

  test("multiply 함수는 정상적으로 작동한다.", () => {
    expect(math.multiply(2,3)).toBe(6);
  });
});

 

 

만약 __mocks__ 폴더에 math.js라는 manual mock이 없을 경우에는 jest는 원본 모듈을 그대로 사용하게 되어, 원본 모듈의 함수들이 실제로 호출되므로 테스트가 실패한다. 

 

'Testing > Jest' 카테고리의 다른 글

Jest: Only와 Skip 사용해보기  (0) 2024.09.18
Jest : Matcher에 대해서  (1) 2024.09.18
Jest : 테스트 전 후 작업 설정하기  (0) 2024.09.11
Jest: 비동기 코드 테스트하기  (0) 2024.09.11
Jest 사용하기  (0) 2024.09.10