함수가 몇 번 호출되었는지, 어떤 인자를 받으며 호출되었는지 등에 대한 테스트 코드 작성 방법을 정리한다. 또한 아래의 등장하는 메서드들은 모두 mockFn에서만 사용이 가능하다. 즉, 진짜 함수에서는 사용하지 못한다. 하지만 jest.spyOn()을 이용하여 진짜 함수에서도 사용을 할 수 있다. 해당 방법도 정리한다.
2. .toHaveBeenCalled()
일반 함수가 아니라 mockFn에서만 사용가능 하다.
mockFn가 호출 되었는지 확인하는 메서드이다. 바로 코드를 작성해보자.
test('test', () => {constadd= (a, b) => a + b;add(1,2);expect(add).toHaveBeenCalled();});
위의 테스트 결과를 예상해보자. 성공했을까? 그렇지 않다. 위의 테스트는 실패한다. 그 이유는 Matcher error 메시지에서 찾을 수 있다.
참고로 .toHaveBeenCalled()와 같은 expect의 메서드가 Matcher이다.
Matcher error를 보면 received value must be a mock or spy function이라는 문구를 볼 수 있다. 즉, 이를 정리하면 아래와 같다.
.toHaveBeenCalled()는 mockFn에서만 사용이 가능하다.
그럼 mockFn을 만들어 테스트를 진행해보자.
test('test', () => {constadd= (a, b) => a + b;constmockFn=jest.fn(add);mockFn(1,2);expect(mockFn).toHaveBeenCalled();});
테스트가 정상적으로 동작하는 것을 확인할 수 있다.
호출을 하지 않을 경우의 테스트는 .not을 작성하면 된다. 아래는 해당 경우의 예시이다.
test('test', () => {constadd= (a, b) => a + b;constmockFn=jest.fn(add);expect(mockFn).not.toHaveBeenCalled();});
3. .toHaveBeenCalledTimes(number)
일반 함수가 아니라 mockFn에서만 사용가능 하다.
mockFn가 몇 번 호출되었는지 확인하는 메서드이다.
test('test', () => {constadd= (a, b) => a + b;constmockFn=jest.fn(add);mockFn(1,2);mockFn(2,3);expect(mockFn).toHaveBeenCalledTimes(2);});
마지막에 호출된 mockFn의 인자를 확인하는 것이 아니라, 특정 순서에 호출된 mockFn의 인자를 확인하는 메서드이다.
constintroduceEach= (fn, arr) => {arr.forEach(({ name, age }) =>fn(name, age));};test('test', () => {constintroduce= (name, age) =>`My name is ${name} and i'm ${age} years old`;constmockFn=jest.fn(introduce);introduceEach(mockFn, [ { name:'HD', age:29 }, { name:'KH', age:27 }, { name:'GY', age:30 }, ]);expect(mockFn).toHaveBeenNthCalledWith(2,'KH',27);});
7. jest.spyOn(object, methodName)
mocking에는 spy라는 개념이 있다. spy이는 말 그대로 스파이의 역할을 한다. 즉, 진짜 메서드의 정보를 몰래 빼내는 역할을 한다.
이를 이용하여 굳이 mockFn를 만들지 않고 메서드의 호출을 테스트할 수 있다.
예시를 통해 구체적인 사용을 알아보자.
test('test', () => {constcal= {add: (a, b) => a + b, };constspyFn=jest.spyOn(cal,'add');cal.add(1,2);cal.add(2,3);expect(spyFn).toHaveBeenCalledTimes(2);expect(spyFn).toHaveBeenLastCalledWith(2,3);});
어떤 메서드에 스파이를 달기 위해선 메서드는 객체에 포함되어 있어야 한다. 위의 예시에선 cal이라는 객체 내에 add 메서드가 있다. 이 add 메서드에 스파이를 달았다.
첫 번째 인자론 객체, 두 번째 인자론 문자열로 메서드 이름을 문자열로 넣으면 된다.
실제로 호출된 메서드는 cal.add()이고 이에 대한 정보를 몰래 캐고 있는 spyFn을 가지고 테스트를 진행하고 있다.
8. Conclusion
함수의 호출 테스트에 관련된 다양한 .toHaveBeen** 메서드에 대해 알아보았다. 또한 jest.spyOn() 함수도 알아보았는데 이는 실제 테스트 코드를 작성할 때 유용하게 사용될 듯 하다. Jest에는 정말 다양한 메서드들이 존재한다. 많은 것들을 한 번에 정리하고 적용할 수 없지만 지금처럼 조금씩 꾸준히 학습을 이어나가도록 하자. 물론 실전에 적용도 필수이다!