on
TDD 단위 테스트란? 6편
TDD 단위 테스트란? 6편
※ 개인 공부를 위한 공간입니다. 틀린 부분 지적해주시면 감사하겠습니다 (_ _)
지난 시간에, Setup and Teardown에 대해서 알아보았다.
이번 시간엔, Mock Functions이라는 주제로 넘어가보겠다.
https://jestjs.io/docs/mock-functions
Mock Functions
Mock functions는 함수의 실제 구현부를 지우고, 함수 호출 및 해당 호출에 전달된 파라미터를 캡쳐하고, new로 인스턴스화 할 때 생성자 함수의 인스턴스를 캡쳐하고, 반환 값의 테스트 시간을 구성할 수 있어 코드간의 연결을 테스트 할 수 있다.
아니 이게 무슨 말이냐면..
Mock 함수(모의 함수=가짜로 만든 함수)는 실제 함수 내에 로직에 해당하는 부분들을 적지 않아도 되며,
함수 호출도 할 수 있고 호출에 전달된 파라미터들도 잡아낼 수 있으며,
new로 인스턴스를 만들 때, 생성자 함수의 인스턴스를 잡아낼 수 있으며,
반환할 때의 시간을 조정할 수 있어서 코드간의 연결을 테스트 할 수 있다!
// 잠깐! 생성자 함수란? // 자바스크립트에서는 클래스가 없지만 프로퍼티가 똑같은 객체를 만들 수 있다. // 객체를 생성하고, new 연산자를 이용해 새로운 객체를 생성하는 함수를 생성자 함수라고 한다. // 코드가 더 이해가 빠를 것 같아 코드를 남긴다. // 생성자 함수 function Book(title, price) { this.title = title; this.price = price; } // new로 만든 생성자 함수의 인스턴스 var book1 = new Book("부자아빠 가난한아빠", 10000)
함수를 mocking하는데엔 2가지 방법이 있다.
테스트 코드에서 mock 함수를 생성하거나 실제로 mock 함수를 작성하거나
들어가기에 앞서
jest.fn(implementation)
> mock 함수를 생성할 때 쓴다. optional하게 implementation을 넣을 수도 있다.
const mockFn = jest.fn(); mockFn(); expect(mockFn).toHaveBeenCalled(); // Optional한 implementation도 넣었다. const returnsTrue = jest.fn(() => true); console.log(returnsTrue()); // true;
Using a mock function
callback함수를 실행하는 forEach 함수를 실행하는 테스트를 해보자.
아래 함수를 테스트하기 위해서, mock 함수를 만들고 callback이 예상대로 불러졌는지 mock의 상태를 체크 해보자.
function forEach(items, callback) { for (let index = 0; index < items.length; index++) { callback(items[index]); } } const mockCallback = jest.fn(x => 42 + x); forEach([0, 1], mockCallback); /* mockFn.mock.calls: mock함수에 호출된 횟수 및 arguments를 포함하는 array mockFn.mock.results: { type: '', value: '' } 형태의 array */ // mock 함수는 2번 호출된다. [0, 1] expect(mockCallback.mock.calls.length).toBe(2); // 첫 번째 함수 호출의 argument는 0이다. expect(mockCallback.mock.calls[0][0]).toBe(0); // 두 번째 함수 호출의 argument는 1이다. expect(mockCallback.mock.calls[1][0]).toBe(1); // 첫 번째 함수 호출의 리턴 값은 42이다. expect(mockCallback.mock.results[0].value).toBe(42);
위에서 언급했던,
함수 호출을 몇번 하는지, 함수 호출 시 전달되는 파라미터들도 잡아낼 수 있으며, 리턴값도 알 수 있다!
.mock property
모든 mock 함수는 .mock 프로퍼티를 가지고 있는데, 어떻게 함수가 호출이 됐고 함수가 어떤 값을 리턴하는지에 대한 데이터가 저장되는지를 보여준다. .mock 프로퍼티는 또한 매 호출마다 this의 값을 트래킹하고 검사할 수도 있다.
어떻게 각 함수들이 호출되었고, 생성되었고, 어떤 값을 리턴하는지 확인하기 위해서 테스트에서 유용하게 쓰인다.
// mock 함수를 만든다. const myMock = jest.fn(); // 생성자 함수의 인스턴스를 만든다. a, b const a = new myMock(); const b = {}; const bound = myMock.bind(b); bound(); console.log(myMock.mock.instances); // > [ , ]
Mock Return Values
mock 함수는 테스트 동안 코드 내에 테스트 값을 넣을 수도 있다.
실제 내부 코드를 수정할 필요 없이, mockReturnValueOnce를 통해 지정할 수도 있다.
const filterTestFn = jest.fn(); // 첫 번째 호출 시 true를, 두 번째 호출 시 false를, 세 번째 호출부터는 true를 return! filterTestFn.mockReturnValueOnce(true).mockReturnValueOnce(false).mockReturnValue(true); const result = [11, 12, 13, 14].filter(num => filterTestFn(num)); console.log(result); // > [11, 13, 14] console.log(filterTestFn.mock.calls[0][0]); // 11 console.log(filterTestFn.mock.calls[1][0]); // 12 console.log(filterTestFn.mock.calls[2][0]); // 13 console.log(filterTestFn.mock.calls[3][0]); // 14
Mock 함수를 기본적으로 만드는 방법을 알아보았다.
다음 시간에는, Mock functions편에 이어 Axios를 어떻게 mock 함수로 만드는지에 대해서 알아볼 예정이다.
하나씩 배워가는 재미!
from http://martinkim1954.tistory.com/120 by ccl(A) rewrite - 2021-12-15 07:28:28