Jest, github actions로 Nest.js 유닛테스트 환경 구축하기

Key Kim
8 min readNov 14, 2021

--

개요

1. 테스트 프레임워크 Jest로 Nest.js 유닛테스트를 작성합니다.

2. Mocking을 사용한 기본적인 유닛 테스트를 수행합니다.

3. github actions을 이용해 유닛테스트에 대한 통계 배지를 README.md 에 자동 업데이트합니다.

README에 나타나게될 배지

글에서 다룰 내용의 레포지토리입니다.

위 레포지토리를 git clone 하고, yarn run ci 로 패키지를 설치합니다.

테스트할 기능 작성하기

User라는 테이블에 firstName, lastName 을 조합하여 한국 이름(lastName + firstName)을 반환하는 기능을 개발합니다.

Entity

Controller

userId가 1000 이상인 경우 UnauthorizedException 반환하고,

koreanName , statusCode를 반환하는 API입니다.

Service

controller에서 호출하는 getKoreanUserNameByUserId 를 작성합니다.

UserRepository 에서 findOne함수로 찾은 firstName , lastName 을 사용해

한국 이름을 만들기 위해 lastName + firstName 으로 재조합하여 반환합니다.

다양한 mocking 예시를 위해, 외부 라이브러리 axios를 사용해 HTTP Request 를 발생시키는 awsS3Service.collectApiHit() 를 호출합니다.

awsS3Service.collectApiHit() 는 아래와 같습니다.

class AwsS3Service {    async collectApiHit() {
return axios.post("https://my-awesome-api");
}
}

이제 테스트 코드를 작성해보러 갑니다.

테스트 기본 설정

7, 83 line

beforeAll afterAll 은 모든 테스트가 시작/종료될 때 한번 호출되는 블록으로, init clean 에 해당하는 코드를 각각 넣어줍니다.

8 line

const moduleFixture 에 테스트 하려는 대상의 모듈이 사용하는 Dependency를 지정해줍니다.

16 line

Axios를 사용하는 collectApiHit() 함수는 useValue 를 이용해

{
status: 200
}

를 리턴하도록 통채로 mocking 해줍니다.

59 line

it.each 에 파라메터로 2차원 배열을 넘기면, 여러 데이터셋으로 테스트를 여러번 진행할 수 있습니다.

it.each 는 아래와 같이 2차원 배열을 매개변수로 받아 처리합니다.

const testcases1 = [        
[
{ input: "hi! input"},
{ output: "hi! output" }
]
]

it.each(testcases1)('input : %s output: %s', async (input, output) => ..
------
>>> input : { input: "hi! input"} output : { output: "hi! output" }

이를 이용해 testcase1 testcase2 변수를 생성합니다.

첫 번째 테스트

한국 이름 반환 기능을 테스트합니다.

60 line

spyOn 을 이용해서 함수 실행과정에서 mocking 하려는 함수를 지정하고,

.mockResolvedValue 로 해당 함수가 반환할 값을 지정해줍니다.

위에서 userRepository.findOne 함수로 데이터베이스에 접근하므로, 이를 mocking하여 firstName lastName 을 우리가 원하는 값으로 반환하도록 지정해줍니다.

69 line

mocking이 끝났으므로, API의 진입부인 controller를 실행시킵니다.

71~73 line

expect 를 사용해 테스트 결과를 검증합니다.

mocking한 userRepostiory.findOne 가 호출되었는지 toHaveBeenCalled 로 체크하고, toEqual 로 위에서 작성한 한국 이름 반환 기능의 결과와 입력한 output을 비교합니다.

두 번째 테스트

userId가 1000 이상이면 UnauthorizedException 을 발생시키는 조건문을 테스트합니다.

78 line

1000 이상인 userId를 controller에 전달하고, .rejectsUnauthorizedException 가 발생하는지 체크합니다.

실행결과

테스트 커버리지 업데이트하기

README.md를 아래와 같은 양식으로 수정해줍니다.

| Statements | Branches | Functions | Lines |
| -----------|----------|-----------|-------|
| ![Statements](#statements# "Make me better!") | ![Branches](#branches# "Make me better!") | ![Functions](#functions# "Make me better!") | ![Lines](#lines# "Make me better!") |

commit, push시 README.md에 테스트 커버리지를 업데이트 해줄 github actions를 작성합니다.

마지막으로 push를 수행하면, 테스트 커버리지가 README.md에 적용됩니다.

github actions이 수행한 commit
최종 README.md

--

--