Study/Test Code

Unit test Testcode 작성하기 - Nestjs, Typescript

isjiji 2025. 9. 13. 18:44

디저트타임 배포전, 잔잔바리 오류들이 생겨나고 개발할 때 확인하지 못했던 문제들을 발견하면서 test code의 필요성을 알게되었다. 

 

test code의 필요성

1. 기획변경 혹은 설정변경, 오류 등으로 인한 소스코드 수정을 했을 경우, 다른 코드나 데이터도 변경이 필요해지는데 그 지점을 test code를 작성함으로 좀더 쉽게 찾을 수 있을것이다.

2. 내가 짠 소스코드가 원하는 결과를 정확히 이행하는지, 즉 기획에 맞는 결과물을 내고있는지 검산이 필요하다.

3. 프로그램의 안정성과 완성도를 높힐 수 있다.

4. 스스로가 코드에 대한 확신이 생긴다. 

 

 

test code를 작성하지 않은 이유

1. 빠르게 소스코드를 치고싶은 마음이있었다. 빠르게 만들고 빠르게 끝내야지! 하는 마음으로 작성을 하지않았는데, 오히려 이후에 오류를 찾아내고 수정하는 시간을 들이는 것을 보며 필요성을 느꼈다. 

 

 

 

 

공식문서를 참고

https://docs.nestjs.com/fundamentals/testing

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea

docs.nestjs.com

 

 

 

 

 

testcode를 작성하기 전에 궁금했던 사항은 다음 네가지이다. 

  1. repository도 unittest를 해야하는가 ? 
  2. 레이어를 mock해서 다음 레이어를 테스트 하듯이, entity나 dto도 mock해야하나?
  3. controller는 주로 e2e로 http test를 한다는데, 그럼 unit test가 필요 없나?
  4. test case는 얼마나 세분화 해서 만들어야하나? (CRUD별 testcase의 세분화정도가 다를것 같음)

 

 

 

궁금증에 대한 답변 정리

  1. repository도 unit test를 해야하는가 ? 
    1. ORM이 제공하는 기능을 thin wrapper(실제 로직이 없고 단순히 ORM 메서드 호출)로 감싼 경우. 즉 findOne, save, update는 이미 ORM이 검증한 기능이라 단위테스트를 작성할 필요는 없음
    2. 커스텀쿼리, 비지니스로직이 들어간 경우에는 test를 작성하는게 좋음 (QueryBuilder, rawSQL)
    3. Repository는 테스트 우선순위가 가장 낮음. Service, e2e에서 대부분 커버됨
  2. 레이어를 mock해서 다음 레이어를 테스트 하듯이, entity나 dto도 mock해야하나?
    1. entity, dto는 단순구조체라 로직이 없는 경우가 대부분임 그럼 mocking의 대상이 되지 않음. 
    2. new 를 사용해서 실제 entity instance를 만들어서 사용하면 됨.
    3. mock이 필요한건 service, repository 와 같은 의존성이지 단순 데이터 객체는 실제 인스턴스를 쓰는것이 자연스러움
    4. 하지만 ! 페이지네이션, 날짜 변환 등 전처리 로직을 넣어둔 경우에는 테스트를 해야한다. 왜? 내가 쓴거니까 버그가 숨어있을수도 있음 ! 
  3. controller는 주로 e2e로 http test를 한다는데, 그럼 unit test가 필요 없나?
    1. 맞음 ! controller에는 비지니스로직이 거의 없고 단순 service만 호출하기 때문에 e2e test에서 한번에 검증하는것이 효율적임
    2. 하지만 ValidationPipe, Decorator, Response 변환 로직같은게 커스텀으로 들어가 있으면 unit test를 작성하는 것이 안전함
  4. test case는 얼마나 세분화 해서 만들어야하나? (CRUD별 testcase의 세분화정도가 다를것 같음)
    1. Create 
      1. 성공케이스 : 정상입력, 저장 후에 반환되는 값 확인 (id)
      2. 실패케이스 : 필수값 누락, 중복, 키제약조건 위반 등 에러시 예외를 잘 던지는지 확인
    2. Read
      1. 성공케이스 : 존재하는 ID 조회 후 올바른 엔티티 반환하는지 확인
      2. 실패케이스 
        1. 존재하지 않는 ID 조회 후, Exception 발생잘하는지 확인 (NotFoundException)
        2. 권한 체크 있는경우 : 접근권한 없는 사용자 접근시  Exception 발생 확인 (ForbiddenException)
    3. Update
      1. 성공케이스 : 존제하는 엔티티 업데이트 후 값이 잘 변경되었는지 확인
      2. 실패케이스
        1. 존재하지 않는 ID 업데이트 후, Exception 발생잘하는지 확인 (NotFoundException)
        2. 잘못된 입력값 업데이트 (null, 음수 등) , Validation에러 발생 하는지 확인 
        3. 권한 체크 있는경우 : 접근권한 없는 사용자 업데이트시  Exception 발생 확인 (ForbiddenException)
    4. Delete
      1. 성공케이스 : 존재하는 ID 삭제 후, 해당 ID 존재 안되는지 확인
      2. 실패케이스
        1. 존재하지 않는 ID 업데이트 후, Exception 발생잘하는지 확인 (NotFoundException)
        2. 권한 체크 있는경우 : 접근권한 없는 사용자 삭제시  Exception 발생 확인 (ForbiddenException)
        3. DB 제약조건으로 삭제가 불가능한 경우, 예외처리 확인

 

 

 

그렇다면 test code를 작성할 때는 어떤 흐름이나 구조로 생각해야할까? 

testcode를 많이 짜보지 않았기 때문에 늘 이부분이 혼란스럽고 어렵게 다가왔다. 혹시라도 test case가 충분한 검증을 못한다면? mock이 무쓸모한 결과를 가져온다면? 그리고 과거 testcase를 작성할 때, 이렇게 데이터를 직접 주입해주면 testcase의 오류를 검증할 수 있나? 하는 고민도 있었다. 

이런 질문에 대한 정리! 

 

 자세한 내용은 아래 참고 ! 

https://isjiji.tistory.com/111

 

Test Code 작성 시, 규칙정하기 (Node.js, Nest.js, TypeScript)

앞 글 참고 ! https://isjiji.tistory.com/103 Unit test Testcode 작성하기 - Nestjs, Typescript디저트타임 배포전, 잔잔바리 오류들이 생겨나고 개발할 때 확인하지 못했던 문제들을 발견하면서 test code의 필요성

isjiji.tistory.com