Projects/Java [Personal]

Test - 1부

montmer27 2026. 2. 12. 01:03

테스트의 중요성

- 좋은 테스트는 좋은 코드를 만들어낸다

: 의존성이 낮고 응집도가 높은, 기능별로 분리가 잘 되어 있는 코드가 테스트에 용이하기 때문에

 

단위 테스트와 통합 테스트의 차이

 

- Bean 등록

- SpringBootTest 실시

- Mock 객체 생성 

  단위 테스트 통합 테스트
Bean 등록 X O
SpringBoot Test X O
Mock 객체 생성 일반적으로 X O

 

기타 테스트

  • 컨트롤러 테스트: Slice 테스트에서 수행
  • 엔드투엔드(E2E) / 시스템 테스트: 시나리오 기준 테스트

좋은 테스트의 원칙 - F.I.R.S.T.

좋은 테스트의 특징

  • 명확한 의도
  • 적절한 범위
  • 도메인 언어 사용
  • 간결한 픽스처
  • 경계값 및 예외 흐름 포함

나쁜 테스트의 특징

  • 비일관적
  • 느림
  • 과도한 Mock
  • 거대한 픽스처
  • 은근한 순서 의존
  • 단정 부족

주의해야 할 점

  • 단위 테스트에 @SpringBootTest 사용
  • 배포 환경과 다른 DB 활용
  • 외부 API 실제 호출
  • 시간 의존 제거: LocalDateTime.now() 대신 Clock 주입

테스트케이스를 올바르게 작성하는 법

Given-When-Then 패턴

Given: 입력/상태/픽스처 구성

When: 대상 메서드 호출 또는 요청 수행

Then: 기대 결과를 단정문으로 명확히 확인

 

테스트 네이밍 규칙: 행위_조건_기대결과 또는 메서드_조건_결과 형태로 통일

 

핵심 규칙은 단위 테스트, 인프라/협력은 통합 테스트로 보강

시나리오 & 비즈니스 규칙을 정리해야 깔끔해진다.

 

BDD 시나리오 - 시나리오를 먼저 테스트해 보고 시나리오가 이상이 없으면 핵심 규칙을 검증한다.

 

테스트에는 정답이 없다.

 

테스트를 적용하는 과정에서 서비스 로직이 개선되는 원리 - 테스트를 편하게 적용하기 위해서 서비스 로직의 개선이 필요하기 때문

 

단위 테스트란? 객체의 메서드 단위로 하나씩 테스트하거나, 메서드가 실패했을 때 어떤 예외를 던질 것인가를 테스트하는 것. 단위 테스트는 대부분 메서드 단위

 

단위 테스트 전, 테스트 가치를 먼저 판단해 보자. 

테스트 가치가 없는 것은 무엇인가?

  • 너무 단순한 경우
  • 지금 테스트하려는 로직이 아닌 경우

테스트 가치가 있는 순수 자바 코드만 별도의 클래스 내 클래스 메서드로 분리한 뒤, 해당 클래스 메서드를 테스트한다.

 

목킹이 필요한 경우: 가짜 객체 연결이 필요한 경우

 

테스트 필요한 로직 옮기기(불필요한 부분까지 포함해서)

 

given 절은 원래 제일 귀찮다.

 

목킹은 규모가 큰 코드에선 부적합하다. 따라서 리팩토링을 하면서 필요한 부분만 따로 추출하여 테스트하는 것이 적합하다. 

 

테스트할 코드만 뽑아내는 과정에서 리팩터링이 이루어짐. 단, 무리해서 할 필요는 없음. 연관과 참조가 너무 복잡할 경우, 또는 분리가 크게 의미 없을 경우 리팩토링은 크게 의미가 없다. 

 

반드시 별도의 클래스를 만드는 것이 능사는 아님. 하지만 테스트하려면 별도의 클래스의 public 메서드여야 함.

 

비즈니스 로직에 테스트를 위한 코드를 넣을 수는 없다.

 

리팩터링의 목적은 책임 분산과 이를 통한 테스트 용이성이다.

따라서 내가 테스트 또는 리팩터링하고자 하는 코드가 어떤 역할과 책임을 가지고 있는지 분석하는 것이 중요하다.

 

예를 들어 다양한 repository에서 데이터를 조회, 저장하는 역할 / 저장한 데이터를 기반으로 새로운 데이터를 만들어 반환해주는 역할이 있을 수 있다.