Unit Test 주의할 점

룰루팍 Lolo Park ·2022년 12월 21일

TDD

목록 보기
1/2

Unit Test 란 각각의 모듈에 대한 test code를 작성하여

  • test code 작성 시, test 하려는 코드(모듈)의 success message와 error message와 response 하는 status code를 동일하게 맞춰줘야한다. 세가지의 test 함수를 돌릴 것이고, 코드를 잘 보면 각각의 시나리오가 있다

    • FAILED -> email 양식을 맞추지 않은 시나리오
    • SUCCESS -> 성공하는 시나리오
    • FAILED -> 이미 있는 email을 기입한 시나리오

    이 시나리오는 내가 회원가입(signUp)코드에서 발생할 수 있는 error들을 정의해놓은 것들과 동일해야한다. error message와 status code도 동일해야하고
    .send({ }) 안에 들어가는 key값도 동일해야한다.

    Layered Pattern을 적용하며 코드가 복잡해지다 보니 어떤 시나리오에 내가 어떤 error message와 statusCode를 적용해놓았는지 찾기가 힘들었다.(사실 따지고 보면 몇개 없기는 한데... 하도 errror를 던져놔서. 이래서 global error handling이 필요한 건가?)

    내가 어떤 error를 던진 건지 헤깔리면 httpie 통신을 이용하여 확인해보는 것도 좋은 방법

  • FOREIGN KEY 설정 해제 필요

const request = require("supertest");

const { createApp } = require("../app");
const { appDataSource } = require("../src/models/data-source");

describe("Sign Up", () => {
  let app;

  beforeAll(async () => {
    app = createApp();
    await appDataSource.initialize();
  });
 
  afterAll(async () => {
    await appDataSource.query(`TRUNCATE users`);
    await appDataSource.destroy();
  });

  test("FAILED: invalid email", async () => {
    await request(app)
      .post("/auth/signup")
      .send({ email: "wrongEmail", password: "password001" })
      .expect(400)
      .expect({ message: "invalid email" });
  });

  test("SUCCESS: success", async () => {
    await request(app)
      .post("/auth/signup")
      .send({ email: "lolo@gmail.com", password: "password001" })
      .expect(201);
  });

  test("FAILED: duplicated email", async () => {
    await request(app)
      .post("/auth/signup")
      .send({ email: "lolo@gmail.com", password: "password001" })
      .expect(400)
      .expect({ message: "duplicated email" });
  });
});

여기서

afterAll(async () => {
    await appDataSource.query(`TRUNCATE users`);
    await appDataSource.destroy();
  });
  
→ truncate users : users 테이블의 데이터를 지우겠다라는 것이다.
→ 하지만 이렇게만 적으면 아래와 같은 error가 발생한다

▼ Error : QueryFailedError : Cannot truncate a table referenced in a foreign key constraint

이 error를 보고 users 테이블에는 foreign key가 걸린 게 없는데 무슨말인가? 라는 생각을 했다.
하지만 우리는 users 테이블의 id가 다른 테이블에 foreign_key로 걸려있는 것이 애초에 error의 원인이였다고 생각을 해야한다. 그래서 이 users 테이블의 id가 어딘가에 fkey로 걸려있을 지 모르니 그것을 먼저 해제해주어야 한다!!!!

그렇기 위해서는
이렇게 sql문을 사용하여 제약조건(constraint)을 잠시 해제해주어야한다

`SET foreign_key_checks = 0` ===> foreign_key constraint를 해제
`SET foreign_key_checks = 1` ===> foreign_key constraint다시 설정

학습자료에는

await appDataSource.query(`TRUNCATE users`);

이것만 나와있어서 어떻게 해야할지 몰랐는데, error를 찬찬히 생각해보면 역시 답이 있다.. (민식님 감사)

근데 이 UNIT TEST 의 coverage 를 확인해보기위해

명령어 npx jest --coverage 를 쳤더니
안됨.. 알고보니 package.json에서 scripts 적어준 부분에 여기에 --coverage를 붙여줘야하는 거였다. 하하하하하하 정수님 감사

package.json 의 script 를 저렇게 설정해주고 다시
npm test 했더니 빨간글씨의 향연 ^^

★ 중요 ★

  • Unit Test 를 하기 위한 database를 새로 만들어야하고, 거기에 내 local database와 동일한 테이블들이 다 세팅되어있었어야 함
  • 그렇다고 dump를 하지는 말고 unit test 코드를 통해서 Database에 데이터들이 들어갔다 나올 수 있도록만
profile
Korean-Arabic Translator, Backend Developer

0개의 댓글