Jest - Mocking이란? (1)
서론
저번 게시글에서 우리는 Unit Test에 대해서 알아보았다.
하지만 Unit Test를 진행하며 어떻게 상위 모듈과 다른 기능을 만들기 전에 해당 기능만을 독립적으로 테스트 할지에 대한 의문이 들었을 수도 있다.
이때 사용하는 것이 Jest에 Mocking 이라는 기능이다.
Mocking?
Mocking에서 Mock은 모조품이라는 뜻으로 테스트하고자하는 코드가 의존하는 함수나 클래스를 모조품으로 만들어 사용하는 것이다.
즉, Unit Test를 진행할 때, 해당 코드가 의존하는 부분을 임의로 만든 모조품으로 대체하는 기법을 말한다.
왜 해야할까?
테스트하려는 기능이 만약 다른 기능에 의존하고 있다면 온전히 그 기능만을 정확히 테스트하기 어렵기 때문이다.
만약 데이터베이스에 데이터를 넣는 기능을 테스트한다고 치자.
그러면 테스트를 해야하는 것이 그 기능뿐만이 아니라 데이터베이스가 제대로 돌아가는지, 그 사이에 ORM, Entity 등 여러 모듈들이 제대로 돌아가는지 또한 테스트 해야한다.
이러한 테스트 방식은 Unit Test 방식에 맞지 않다.
그렇기 때문에 데이터베이스를 실제로 동작시켜서 테스트하는 것이 아닌, 데이터베이스와 그 외 모듈들이 동작이 잘되었다고 가정하고 테스트를 하기 위해 Mocking 기법을 사용하는 것이다.
즉, 데이터베이스에서 반환되어야하는 값을 임의로 정하여 실제 데이터베이스를 사용하지 않고, 해당 기능만이 제대로 작동하는지를 정하는 개념이다.
Jest에서의 Mocking
Jest에서는 여러가지 Mocking 메소드를 지원해준다.
jest.fn
mockReturnValue(value)
함수에서 반환하는 값을 임의로 지정할 수 있다.
javascript1const mockFunction = jest.fn(); 2 3mockFunction() // mockFunction은 임의로 만들어진 Mocking 함수이기때문에 undefined 를 반환한다. 4 5mockFunction.mockReturnValue('Hello World!'); // mockFunction 에서 Hello World 를 반환하게 설정한다. 6 7mockFunction() // Hello World!
mockImplemetation(value)
Mocking 함수는 기본적으로 아무것도 동작하지않고, 아무것도 반환하지 않는다.
mockImplemetation() 함수를 사용하면 Mocking 함수의 동작을 즉석해서 구현할 수 있다.
javascript1const mockFunction = jest.fn(); 2 3mockFunction.mockImplemetation((value) => { 4 console.log('hello' + value); 5}) 6 7mockFunction('james') // hello james
위와 같이 임의로 함수의 동작을 결정할 수 있다.
이 함수를 사용하지 않고 아래와 같은 방식으로도 가능하다.
javascript1const mockFunction = jest.fn((value) => { 2 console.log('hello' + value); 3}); 4 5mockFunction('james') // hello james
mockResolvedValue(value) / mockRejectedValue(value)
Mocking 함수에서 비동기 함수를 처리할 때 사용하는 메소드이다.
Promise 에서 Resolve 혹은 Reject를 반환한다.
javascript1 2const resolveFunction = jest.fn().mockResolvedValue(0); 3 4await mockFunction() // 0 5 6const rejectFunction = jest.fn().mockRejectedValue(0); 7 8await rejectFunction() // throws "Async error"
그 외 기능
그 외에 Mocking 함수가 유용한 이유는 자신이 어떻게, 언제 호출 되었는지 기억하고 있다는 점이다.
javascript1//... 2 3it('should be defined', () => { 4 const mockFunction = jest.fn(); 5 mockFunction.mockImplementation((value) => { 6 console.log("Hello " + value); 7 }) 8 9 mockFunction("a"); 10 mockFunction(["b","c"]); 11 12 13 expect(mockFunction).toBeCalledTimes(2); // mockFunction이 2번 호출되었는가? true 14 expect(mockFunction).toBeCalledWith("a"); // 매개변수로 a를 받았는가? true 15 expect(mockFunction).toBeCalledWith(["b", "c"]); // ["b","c"] 라는 배열을 매개변수로 받았는가? true 16}); 17 18//...
이와 같이 자신이 몇번 호출되었는지 매개변수로 무엇을 받았는지 등 어떻게 동작되었는지를 기억하고 있기때문에 개발자가 의도한대로 어플리케이션이 돌아가는지 확인하는데 용이하다.
마치며
오늘은 Mocking 이 무엇인지 그리고 Jest에서는 어떻게 구현하는지에 대해서 알아보았다.
다음 게시글에는 Jest에서 Mocking 을 구현하는 추가적인 방법에 대해서 알아보자.