[Nest] 단위테스트하기(feat. jest)

주형(Jureamer)·2022년 4월 7일
3

개요

파이널 프로젝트가 끝나고 리팩토링 대상을 정의하다가 많은 소프트웨어 개발 방법론 중 TDD(테스트 주도 개발)에 관심이 생겨 기존 작성 코드에 단위테스트를 추가하고, 신규 개발도 단위테스트 기반으로 개발하기로 팀원과 결정했다!

단위테스트 작성 With JEST

Nest는 기본적으로 JEST를 이용한 testing을 지원한다.
CLI를 통해 controller, service 파일을 만들면 끝이 spec.ts(Typescript 사용 시)로 끝나는 파일이 만들어 지는데 해당 파일을 이용하거나 직접 spec.ts, test.ts 파일을 만들어 테스트 할 수 있다.

Package.json 설정

아마 TS를 사용하는 경우 테스트를 시도하게 되면 import하는 부분이 에러가 날 건데 경로를 절대경로를 읽을 수 없어서 그렇다고 한다. 그렇기 때문에 Package.json에서 아래와 같이 module name mapper 옵션을 추가 해주고 사용하자.

Repository 함수 Mocking

Mocking이란? Mock(흉내내기)라는 뜻으로 Mock 함수는 아래와 같은 기능을 제공한다.

  • 함수 호출 Capture
  • Return Value 설정
  • 구현 변경하기

모듈과 함수를 Mock하는 방법

  • jest.fn: Mock a function
  • jest.mock: Mock a module
  • jest.spyOn: Spy or mock a function

나는 jest.fn()을 통해 Repository내에서 사용되는 함수들을 mocking했고 예시는 아래와 같다.

Utility Type을 활용한 Mock Type
Mocking한 Repository의 타입을 지정해주기 위함이다.
Record를 통해 모든 타입을 mocking한 뒤 partial을 통해 부분적으로 사용할 수 있게 만들어 주었다.

모듈 지정과 관련된 코드는 아래와 같다.

실제 테스트

beforeEach/beforeAll, afterEach/afterAll을 통해 테스트 전후로 중복해서 실행할 수 있는 부분을 지정할 수 있다.

나는 각 테스트 전에 함수마다 mockResolvedValue 지정을 해주었다.

실제 테스트 코드는 아래와 같이 적용해주었다.

service.searchArticle 메소드에서 실행되는
Repository 함수들은 beforeEach 단계에서 mocking되어 가짜 value가 return 되어 원하는 값이 도출되면 테스트 성공으로 해주었다.

에러 처리
허용되지 않는 값(undefined)을 mockValue로 지정하고 try .. catch문을 사용하여 에러 처리를 해주었다.

실제 서비스에 해당하는 로직은 아래와 같다.

Testing 결과!!

후기

일단 테스팅 툴을 처음 써본 거기도한데 Nest+Jest로 테스트를 진행했던 예시가 많이 없어서 (특히 유튜브는 거의 영문밖에 없었다.)
초반에 에러를 해결한다던지 module을 선언하는 부분에서 많이 벅찼었다.
다른 팀원들도 다 처음이었기 때문에 지속적으로 소통하면서 문제를 공유하고 어려움을 나누는 과정들을 겪었다.
(처음엔 service를 testing하는데 service와 repository를 모두 mocking하는 걸로 착각도 했다...ㅠ)
특히 팀장님께 많은 인사이트를 얻어서 결실을 이룰 수 있었던 것 같다.

사실 이번에 진행했던 단위테스트는 기존에 이미 짜있던 로직에 대해서 단위테스트를 적용한 것이라 취지와는 좀 안맞을 수 있다.
하지만 이제 작성법을 깨달았으니 실제로 개발할 때도 단위테스트를 통해 개발해보자!

Reference

profile
작게라도 꾸준히 성장하는게 목표입니다.

0개의 댓글