본문 바로가기
Language/Node.js

[JEST] Supertest

by 노믹 2022. 12. 29.

Supertest란?

supertest는 jest와 함께 사용하여 부분적인 테스트 뿐만 아니라, 원하는요청(Request) 를 이용해 반환(Response)된 정보를 검증하기 위해 사용되는 대표적인 테스트 라이브러리입니다.

supertest는 저희가 구현한 Express.js를 이용해 통합 테스트(Integration Test)를 구현할 수 있는 테스트 라이브러리입니다. 대표적으로 Express의 서버를 구동시켜 가상의 API 요청(Request)을 보내고 원하는 결과가 발생하였는지 검증할 수 있습니다.

저희가 구현할 통합 테스트는 supertest 라이브러리 하나만을 이용해 테스트 코드를 구현할 것이 아닌, jestsupertest를 함께 사용해 더욱 명확하게 테스트 코드를 구현할 예정입니다.

 

supertest를 이용해 테스트 코드를 작성하는 예시는 아래와 같습니다.

const supertest = require("supertest");
const app = require("../../app.js");

const response = await supertest(app)
  .post(`/api/posts`) // API의 HTTP Method & URL
  .query({}) // Request Query String
  .send({}) // Request Body
  • 계층별 단위 테스트를 구현한 것과 다르게, supertest를 이용한 통합 테스트의 경우 Http Method, API의 URL을 입력하여 테스트를 진행합니다.
  • supertest의 공식 예제는 메서드 체이닝(Method Chaning) 형식으로 테스트를 진행하지만, 반환된 Response의 값을 기준으로도 테스트 코드를 작성할 수 있습니다.

 

supertest의 문법 살펴보기

  • .post(”URL”) : Http Method와 URL을 입력해 테스트 하려는 API를 호출할 수 있습니다.
  • .query(object) : API에게 Query String을 이용해 데이터를 전달합니다.
  • .send(object) : API에게 Body에 데이터를 전달합니다.
  • response : supertest를 이용해 API를 수행한 반환(response)값이 할당됩니다.
    • response.type : Response Header의 Content-type의 값입니다.
    • response.body : API Response의 반환된 json 데이터입니다.
    • response.headers : API Response에 반환된 헤더 정보입니다.
    • 이외에도 response에는 다양한 반환값이 존재합니다!

supertest에 대해 자세하고 알고싶다면 여기를 클릭해주세요!

 

Sequelize Test DB 설정하기

  • SequelizeMySQL을 연결할 때, NODE_ENV를 test로 설정할 경우 기존에 설정된 DB가 아닌, config.json에 test 부분에 설정된 값으로 DB를 연결 할 수 있습니다.
  • 통합 테스트(Integration Test)를 실행할 때, 기존에 사용하는 Development 환경이 아닌, test DB를 사용할 경우 데이터를 언제든지 자유롭게 관리 할 수 있고, 생성삭제가 쉽게 가능해집니다.
  • config/config.json 파일에서 test 환경을 원하는 DB 설정으로 수정해주세요.
  • config/config.json에 test 환경 설정을 완료하였을 경우 아래의 코드를 실행하여 DB와 Table을 생성해주세요.
# test 환경에 설정값을 이용해 DB를 생성합니다.
NODE_ENV=test npx sequelize db:create

# test 환경에 설정값을 이용해 Table을 생성합니다.
NODE_ENV=test npx sequelize db:migrate

 

통합 테스트 (Intergration Test) app.js 설정

통합 테스트 (Integration Test)를 진행하기에 앞서, 저희는 통합 테스트를 하기 위한 설정을 진행해야합니다. supertest 라이브러리를 사용하기 위해서는 express의 app 객체를 이용하여 테스트를 진행할 수 있습니다. 그렇기 때문에 저희는 app.js 파일에서 express의 app 객체를 export하여 테스트 코드에서 app 객체를 가져올 수 있도록 설정하도록 하겠습니다.

// app.js

...

module.exports = app

 

sequelize.sync 문법

sequelize.sync 문법

  • sequelize.sync(): 테이블이 없는 경우 새롭게 생성합니다. 하지만, 테이블이 이미 생성되어있는 경우 아무런 행동을 하지 않습니다.
  • sequelize.sync({ force: true }): 테이블을 생성하고, 만약 테이블이 존재하는 경우에는 삭제한 후 다시 생성합니다.

beforeAll() 로직

beforeAll(async () => {
  if (process.env.NODE_ENV === 'test') await sequelize.sync();
  else throw new Error('NODE_ENV가 test 환경으로 설정되어 있지 않습니다.');
});
  • beforeAll()에서는 sequelize.sync()를 수행하여, test환경에 있는 MySQL의 테이블들을 생성합니다.
  • test 환경이 아닐때에는 에러가 발생하여 테스트 코드가 실패하도록 작성되어있습니다.
  • 테이블이 존재하지 않아 통합 테스트가 실패하는 경우를 방지할 수 있습니다.

afterAll() 로직

afterAll(async () => {
  if (process.env.NODE_ENV === 'test') await sequelize.sync({ force: true });
  else throw new Error('NODE_ENV가 test 환경으로 설정되어 있지 않습니다.');
});
  • afterAll()에서는 sequelize.sync({ force: true })를 수행하여, test환경에 있는 MySQL의 테이블들을 삭제 후 생성(초기화)합니다.
  • test 환경이 아닐때에는 에러가 발생하여 MySQL의 테이블 삭제를 방지합니다.
  • 다음 테스트 코드를 실행할 때, DB의 환경을 처음과 같은 상태로 만들어 편리하게 테스트 코드를 작성할 수 있게 됩니다.