테스트가 어려운 코드
● 하드 코딩된 경로 : 해당 경로에 파일이 반드시 위치해야함
● 의존 객체를 직접 생성
● 정적 메서드 사용
● 실행 시점에 따라 달라지는 결과
○ LocalDate.now() 혹은 Random 사용하는 코드
● 역할이 섞여 있는 코드
● 메서드 중간에 소켓 통신 코드 포함
+) 소켓 통신이나 HTTP 통신의 경우 실제를 대체할 서버를 로컬에 띄워서 처리 가능 (서버 수준의 대역)
● 콘솔에서 입력을 받거나 결과를 콘솔에 출력
● 테스트 대상이 사용하는 의존 대상 클래스나 메서드가 final : 대역으로 대체하기 어려움
● 테스트 대상의 소스를 소유하고 있지 않아 수정이 어려움
테스트 가능한 설계
테스트가 어려운 주된 이유 = 의존하는 코드를 교체할 수 있는 수단이 없음
● 하드 코딩된 상수를 생성자나 파라미터로 받기
- [어려운 점] 테스트 환경에 따라 경로를 다르게 줄 수 있는 수단 X
- [해결 방법] 생성자나 세터를 이용해서 경로를 전달 받음
ex) 변수로 따로 분리하기, 메서드의 파라미터로 값을 전달받도록 하기
● 의존 대상을 주입 받기
- [해결 방법] 생성자나 세터를 통해 의존 대상을 교체 (: 실제 구현 대신에 대역을 사용할 수 있음)
* 만약 많은 레거시 코드에서 생성자 없는 버전 사용시 → 세터를 이용해서 의존대상 교체하도록 수정
: 이렇게 함으로써 의존대상을 교체할 수 있도록 수정한 것임
테스트하고 싶은 코드를 분리하기
- 기능의 일부만 테스트하고 싶다면 해당 코드를 별도의 기능으로 분리하여 테스트 진행
(+) 일부 기능 자체를 대역으로 변경하고 싶다면 '의존 대상을 주입받기' 에서 설명한 것처럼 세터를 이용해서 의존 대상을 주입
● 시간이나 임의 값 생성 기능 분리하기
- [어려운 점] 테스트 대상이 시간이나 임의 값을 사용하면 테스트 시점에 따라 테스트 결과가 달라짐
- [해결 방법] 테스트 대상이 사용하는 시간이나 임의 값을 제공하는 기능을 별도 분리
* 임의 값을 제공하는 라이브러리를 직접 사용하지 말고, 별도로 분리한 타입을 사용해서 대역으로 처리해야함
● 외부 라이브러리 대체 불가능한 경우 (정적 메서드 제공 시)
- [어려운 점] 정적 메소드들은 상태를 가지지 않거나 전역 상태를 사용하고, mocking이 어려움.
- [해결 방법] 외부 라이브러리를 직접 사용하지 말고 외부 라이브러리와 연동하기 위한 타입을 따로 만듬. 테스트 대상은 분리한 타입을 사용하도록 함 (: 외부 연동이 필요한 기능을 쉽게 대역으로 대체 가능)
테스트 종류

● 통합 테스트
○ 개발 완료 후에 진행하는 최종 테스트
○ 고객의 입장에서 요구한 기능을 올바르게 구현했는지 수행하는 테스트
○ 소프트웨어의 코드를 직접 테스트함
○ 대상 (web app의 경우) : 프레임워크, 라이브러리, 데이터베이스, 구현한 코드
● 인수 테스트
○ 고객의 입장에서 요구한 기능을 올바르게 구현했는지 수행하는 테스트
○ 요건을 완료했는지 정의하기 위해 작성한 테스트
● 기능 테스트
○ 사용자 입장에서 시스템이 제공하는 기능이 올바르게 동작하는지 확인
○ 시스템을 구동하고 사용하는데 필요한 모든 구성요소가 필요함
○ E2E 테스트에 속함
● E2E 테스트
○ 모든 구성요소를 하나로 엮어서 진행 (사용자가 사용하는 웹 브라우저 부터 시작해서 외부서비스, DB에 이르기까지)
● 단위 테스트
○ 개별 코드나 컴포넌트가 기대한대로 동작하는 지 확인
○ 한 클래스나 한 메서드와 같은 작은 범위 테스트
○ 의존 대상의 경우 스텁이나 모의 객체를 이용해서 대역으로 대체
테스트를 자동화한다 == 코드로 작성한 테스트를 실행한다
* 정기적인 기능테스트 = 정상적인 경우와 몇 가지 특수한 상황만 테스트 범위로 잡음
WireMock = 서버 API를 스텁으로 대체
WireMock 사용방법
● 테스트 실행 전에 WireMockServer 시작. 실제 HTTP 서버 뜸
● 테스트에서 WireMockServer의 동작 기술
● HTTP 연동을 수행하는 테스트 작성
● 테스트 실행 후에 WireMockServer를 중지
TestRestTemplate은 스프링 부트가 테스트 목적으로 제공. 내장 서버에 연결하는 RestTemplate.
'Java' 카테고리의 다른 글
| TDD로 기능 추가해보기 (0) | 2025.09.24 |
|---|---|
| TDD 시작하기 (0) | 2025.09.09 |
| 스프링 데이터 JPA (2) | 2025.08.17 |
| 나를 위한 클래스와 객체, 상속 부분 내용 정리 (0) | 2023.05.16 |
| 끝말잇기 게임 만들기 (0) | 2023.05.15 |