이번에는 지금까지 만들었던 API를 테스트를 해보겠다. 기능 개발도 중요하지만 작성된 코드가 더 간단하게 안정적인 애플리케이션이 되기 위해서는 테스트는 필수적이다. 또 디버깅 시간을 단축시킬 수 있다. 만약 데이터가 잘못 나왔다면, UI 문제인지 DB 문제인지 전부 테스트해봐야 하지만 테스팅 환경이 구축되었다면, 자동화된 유닛 테스팅으로 특정 버그를 쉽게 찾을 수 있다.
NestJS에서는 특정 도구를 권하지는 않지만 Jest를 기본 테스트 프레임워크로 제공해 주며 테스팅 패키지도 제공하기 때문에 개발자가 다른 도구를 찾는데 소모하는 리소스를 줄일 수 있다. NestJS에서 제공하는 @nestjs/testing 패키지를 사용하면 테스트에 사용되는 종속성만 선언해서 모듈을 만들고 해당 모듈로 Service, Repository를 가져올 수 있다.
- Install Jest Testing Tool package.
npm i --save-dev @nestjs/testing
Jest에서는 mocking 함수들을 기본적으로 제공한다. mocking은 단위 테스트를 작성할 때, 해당 코드가 의존하는 부분을 가짜(mcok)로 대체하는 기법이다. 일반적으로는 테스트하려는 코드가 의존하는 부분을 직접 생성하기가 너무 부담스러울 때 mocking이 사용된다.
Nest Js는 Controller, Service 등을 묶어 module 파일 내에서 모두 관리한다. 즉 모두 분기시켜서 관리하는 Module을 캡슐화를 시켜놓는다. 따라서 Test 환경 또한 의존성 주입을 해주는 것과 같은 환경을 만들어 주어야 한다. 예를 들어 CatsController를 Test 한다고 가정하면 실제로 CatsController에 영향을 주는 CatsService와 같은 Provider를 mocking 하여 실제 Service에 영향을 주지 않고 Controller를 테스트해야 한다. Testing Tool(Jest)이 src 경로를 찾지 못하는 경우가 있다. Nest JS는 TypeScript를 사용하고 있기 때문에 ../../이런 식으로 없지만 Jest는 그렇지 못한다.
필자는 products.service를 test 한다. 따라서 service에 DI 해주었던 Repository를 mocking 해주어 가짜 가상의 DB와 연결시켜 주었고, createProdcut 비즈니스 로직 안에서 create와 save 함수를 사용하기 때문에 mocking 해준다.
jest.fn()는 mock함수를 생성하는 함수이다. 단위 테스트 작성할때 해당 코드가 의존하는 부분을 가짜로 대체해준다.