Supertest를 활용하다

Sinf·2022년 1월 18일
0

고민의 흔적

목록 보기
13/38
post-thumbnail

Supertest

supertest?

처음 테스트를 작성하기 위해 jest에서 어떻게 테스트하는지 깃허브를 찾아다니면서 Express로 구현된 프로젝트의 테스트 코드를 파헤쳐다녔다.

하나 참고가 될 것 같은 코드를 봤는데, supertest를 활용해 테스트를 진행하고 있었다.

supertest로 테스트를 진행하면 Request에 대한 내용을 작성하면 내가 작성한 서버의 로직을 돌고 Response 객체를 가져오게 된다.

먼저 설치부터 진행한다.

yarn add -D supertest regenerator-runtime

supertest를 async/await로 진행할 것이기 때문에 regenerator-runtime를 함께 받아준다. 이전에는 @babel/pollyfill를 사용해 런타임 문제를 해결했다고 하는데 deprecated 경고가 뜬다. 찾아보니 regenerator-runtime로 해결할 수 있다고 한다.

일단 코드를 보자

app.js

여기서 app.js에 다음과 같은 코드를 넣어 준다.

if (process.env.NODE_ENV !== "test") {
  app.listen(port, () => {
    logger.info(`Start server at ${port}`);
  });
}

이렇게 하지 않으면 jest가 테스트 코드를 병렬적으로 진행할 때, 이미 포트가 사용 중이라고 테스트가 종료되어버린다. test 환경에서 실제로 실행되지 않도록 한다.

post.test.js

import "regenerator-runtime";
import request from "supertest";
import server from "../app.js";

먼저, 패지키를 불어온다. app.js에서 Express app을 가져온다.

it("생성된 포스트 get", async () => {
  const res = await request(server) // 1
    .get("/api/posts/" + postId) // 2
    .send(); // 3
});

코드를 보면, 일단 비동기로 처리되기 때문에 await으로 실행되는 결과를 기다리도록 한다. 만약 async/await이 익숙하지 않다면 Promise 체인으로도 가능하다.

  1. request 객체에 server, express app을 파라미터로 전달한다.
  2. method를 정의하고 url을 파라미터로 전달한다.
  3. send()를 통해 Request 객체를 전달한다.

Request에 사용할 수 있는 함수들이 여러가지 존재한다. 인증을 위해 .set("authorization", token)와 같은 것도 붙일 수 있고, post의 경우 send 내에 객체를 통해 body를 전달할 수 있다.

또한 이미지 전달에 대한 테스트를 진행할 땐, attach를 통해 원하는 파일을 담아 테스트할 수 있다. 다만 이 땐, send를 사용하지 않고 field와 함께 사용한다.

const res = await request(app)
  .post("/api/posts")
  .set("authorization", token)
  .field("title", "title")
  .field("contents", "content")
  .field("wideAddr", "서울특별시")
  .field("localAddr", "강남구")
  .attach("photos", pwd + "/1.JPG");

res에는 해당 Request에 따른 Response 객체가 저장된다.

Response 객체 값 테스트하기

그럼 이제 받아온 Response 객체를 통해 값을 검증한다.

it("생성된 포스트 get", async () => {
  const res = await request(server)
    .get("/api/posts/" + postId)
    .send();

  expect(res.statusCode).toEqual(201);
  expect(Object.keys(res.body)).toEqual(
    expect.arrayContaining(["title", "contents", "author"])
  );
  expect(res.body.title).toEqual("title");
  expect(res.body.author).toEqual("sinf");
});

이것은 기존에 jest를 통해 값을 검증하는 것과 같다.
다만 res.body에 값이 담겨오는 것, res.statusCode에 상태코드가 저장되어 있는 것 기억하면 된다.

값을 테스트하는 것을 더 다양한 방법이 있을 것이다.

profile
주니어 개발자입니다. 🚀

0개의 댓글