Jest 사용법 - mock functions

공식문서에 있는 예제를 통해 기본적인 사용법을 빠르게 익힌다. 따라서 모든 내용은 공식 문서 기반이며, 추후에 테스트를 많이 작성하면서 발생한 엣지 케이스를 이 내용에 덧붙여 추가할 예정이다.

모의 함수(mock function)

mock이라는 단어로 많이 쓰고 그냥 편하게 목 함수라고 말했던거 같다. 하지만 아래에서는 조금 더 이해하기 쉽게 하기 위해 모의 함수라고 쓰겠다. 만약 mock 이라는 단어를 처음 봤다면 아래 사전 뜻을 보고, 그 아래 적혀있는 정의를 읽어본다면 이해하기 더 쉬울 것이다.

모의 함수를 사용하면 함수의 실제 구현을 지우고 함수에 대한 호출과 해당 호출에 전달된 매개 변수를 캡처(capturing)하고, new로 인스턴스화할 때 생성자 함수의 인스턴스(instances)를 캡처하고, 반환 값의 테스트 시간을 구성할 수 있어 코드 간의 연결을 테스트할 수 있다.

아직은 이해가 잘 안될 수 있는 개념이다. 위에 정의 여러번 읽고, 아래 내용을 본뒤 다시 읽어보면 더 이해가 될 것이다.

예제 코드

function forEach(items, callback) {
  for (let i = 0; index < items.length; i++) {
    callback(items[i]);
  }
}

.mock

모든 모의 함수는 .mock이라는 특별한 프로퍼티(property)를 갖는다. 이 프로퍼티에는 모의 함수가 호출된 방법 및 반환된 함수에 대한 데이터가 보관되고 있다. 또한 각 호출에 대한 this 값도 추적하고 있으므로 이를 검사할 수 있다.

const mockCallback = jest.fn((x) => 42 + x);
forEach([0, 1], mockCallback);

// 모의 함수 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);

// 두번째 호출된 모의 함수의 반환 값은 43
expect(mockCallback.mock.results[1].value).toBe(43);

// 이 함수는 정확히 2번 인스턴스화 되었다.
expect(mockCallback.mock.instances.length).toBe(2);

.mock는 이러한 함수가 어떻게 호출되고 인스턴스화되는지 또는 반환된 내용을 확인하는 테스트에서 매우 유용하다.

모의 함수 반환값

모의 함수를 사용하여 테스트 중에 코드에 테스트 값을 삽입 할 수도 있다.

const myMock = jest.fn();
console.log(myMock());

myMock.mockReturnValueOnce(10).mockReturnValueOnce("x").mockReturnValue(true);

console.log(myMock(), myMock(), myMock(), myMock(), myMock());
// 10 "x" true true true

모의 함수는 기능적 연속 전달 스타일을 사용하는 코드에서도 매우 효과적이다. 이 스타일로 작성된 코드는 실제 구성 요소의 동작을 재현하는 복잡한 스텁(stubs)을 피할 수 있도록 도와주며, 사용하기 직전에 테스트에 직접 값을 주입하는 데 도움이 된다.

const filterTestFn = jest.fn();

filterTestFn.mockReturnValueOnce(true).mockReturnValueOnce(false);

const result = [11, 12].filter(x => filterTestFn(x));

console.log(result); // [11]
console.log(filterTestFn.mock.calls); // [[11], [12]]

Last updated