[정리] JEST를 이용한 유닛테스트 방법 간단정리

2021. 1. 29. 14:56프로그래밍-Web/Jest(TDD)

간단하게 사용하던 방식 정리(NodeJS기준)

 

일단 여기에서는 유닛테스트에 jest를 이용한다

jest는 애초에 리액트를 위한 라이브러리라서 nodeJS에서 사용하려면 별도 설정을 몇가지 해줘야 된다.

설정이 다 되어있다는 가정하에 간단한 유닛테스트 예시를 들어보겠다!

 

1) 시작전

 

테스트 관련 코드들은 보통 별개로 작성한다.

내 경우에는 통합테스트와 유닛테스트로 나누어 관리하였다.

 

2) Mock 객체 생성

 

테스트 파일에는 기존에 설정했던 컨트롤러와 모델, 그리고 테스트 데이터를 불러온다

여기에서 httpMocks에 주목해보자

 

jest를 이용한 테스트에서는 Mock함수를 만들어 사용한다

Mocking은 코드가 의존하는 부분을 가짜(mock)로 대체하는 기법을 말한다.

 

모든 유닛테스트에 Mock함수를 적용하는 것은 아니지만, Mock함수를 꼭 사용해야 되는 경우가 있다.

대표적으로 DB 삭제같은 경우, 실제 데이터를 대상으로 테스트를 진행하면 문제의 소지가 있다.

또한 기능 검사이므로 굳이 검사하지 않아도 되는 네트워크 연결, 입출력 등에도 리소스가 소모되는 낭비가 생긴다

무엇보다 유닛테스트의 특정 기능에 대해서만 테스트하겠다는 근본적인 철학에 어긋나게 된다.

이러한 이유로 함수를 실제로 사용하지 않고 가짜로 객체를 만들어내어 사용하는 것을 Mocking이라 하는 것이다

 

보통 Mock함수는 jest에서 제공하는 메소드를 통해 객체를 만들고 콜백함수로 사용한다

 

해당 예시에서는 모델에 create 메소드를 활용해 Mock함수를 만들었다

또한 beforeEach를 통해 해당 테스트 전에 res,req,next도 전부 가상으로 만들어주었다.

이때 req나 res의 경우도 node-mocks-http에서 지원하는 메소드로 Mock을 만들어 줄 수 있다.

 

3) 테스트 그룹 설정

한개의 테스트 단위는 test로 설정하고, test들을 묶어 descirbe로 그룹화 시킨다

test 명령어는 동일하게 작동하는 it으로 대체할 수 있다

 

4) expect, matcher함수

각 test의 내용을 적어주고, 콜백으로 expect와 matcher함수를 설정한다.

expect에는 동작을 기대하는 객체나 함수를 설정해주고, matcher함수로 해당 객체(나 함수)의 작동 결과값을 정의한다.

예시의 경우 productController.createProduct의 type에 대해 function이라는 결과값이 기대됨을 의미한다

 

5) 가상데이터 설정

테스트를 위한 데이터를 설정한다.

미리 json 데이터를 만들어 testProduct라는 데이터를 req.body에 담아놓고 시작하였다.

얘는 req가 제대로 불러와진다면 body에 담겨져 있을 것이다

 

 

6) 실제 API의 경우- 모델호출

해당 테스트코드를 보면 컨트롤러의 createProduct라는 API에 대한 테스트이다

productModel.create 테스트에 대해

가상Mock함수가 반드시 호출되어야 한다는 기대 결과값과,

testProduct라는 데이터가 불러져와야 한다는 기대 결과값을 정의하였다.

이때 가상데이터로 testProduct라는 데이터를 req.body에 담은채 시작했으니, testProduct는 불러와진다.

 

7) 실제 API의 경우 - 리턴값 테스트

실제 컨트롤러의 로직은 다음과 같다

 

우리는 Mock함수를 사용하므로 productController.createProduct를 하면 일정 시간이 흐른 후 Mock함수가 생길것이다.

Mock함수는 실제 컨트롤러의 로직을 그대로 담고 있다.

따라서 res.statusCode를 하면 실제 컨트롤러에서 정의된대로 201이 나올것이다.

 

mockReturnValue는 테스트 코드 작성자가 return value 를 임의로 설정하는 것이다.

이후 res를 부르면 res가 담고있는 데이터에 testProduct가 담겨져있어야 할 것이다.

 

8) 에러테스트

에러테스트도 비슷하다

mockReturnValue로 error시 res를 설정해주었다

기능이 제대로 작동한다면 error시 컨트롤러가 next에 error를 담아주기때문에, 미리 정의해둔 에러메시지가 전달되어야 한다

 

여기서 주의할점은 NodeJS자체가 서버의 index파일에서 에러 핸들링이 되어야 next로 에러 메시지를 넘긴다는 점이다