지난 시간에는 TDD의 개념과 필요성에 대해 알아보았습니다.
이번 시간에는 실제 코드를 작성하기 위한
개발 환경
을 구성해 보겠습니다.
요리를 하기 전에 도마와 칼을 준비하고 재료를 손질하는 단계라고 생각하면 됩니다.
Spring Boot는 테스트를 위한 도구들을 아주 잘 갖추고 있습니다.
우리가 이 도구들의 기본적인 사용법을 익히고, 어떻게 프로젝트를 구성해야 효율적인지 배울 것입니다.
가장 먼저 Spring Boot 프로젝트를 생성해야 합니다.
모두가 동일한 환경에서 실습할 수 있도록
Spring Initializr
사이트를 이용해 세팅하겠습니다.
웹 브라우저를 켜고
start.spring.io에 접속해 주세요.
https://start.spring.io↗
사이트에 접속했다면 아래 항목들을 똑같이 선택해 주세요.
가장 보편적이고 안정적인 설정입니다.
Project:
Gradle - Groovy (빌드 도구)
Language:
Java
Spring Boot:
3.x.x (괄호에 SNAPSHOT이나 M1이 없는 버전 선택)
Project Metadata:
- Group: com.example (원하는 도메인)
- Artifact: tdd-study
- Packaging: Jar
- Java: 17 (가장 많이 쓰이는 LTS 버전)
이 설정은 우리가 집을 지을 때 '철근 콘크리트'로 지을지, '목조'로 지을지 뼈대를 결정하는 것과 같습니다.
우리는 Gradle과 Java 17이라는 튼튼한 뼈대를 선택했습니다.
✅
필수 의존성 (Dependencies) 추가 🔗
오른쪽의
ADD DEPENDENCIES
버튼을 눌러 다음 3가지를 검색해서 추가합니다.
Spring Web
웹 기능을 만들기 위해 필요합니다.
Lombok
코드를 간결하게 줄여주는 도구입니다.
Spring Boot DevTools
서버 재시작 없이 코드 변경을 반영해 줍니다 (선택 사항).
설정이 끝났다면 하단의
GENERATE
버튼을 눌러 압축 파일을 다운로드하고, 압축을 푼 뒤 IntelliJ IDEA에서
build.gradle 파일을 엽니다.

start.spring.io
👨💻
만약 JDK 17이 설치되어있지 않다면 IntelliJ의 Project Structure에서 SDK를 추가해 주세요.
파일 - 프로젝트 구조 - SDK - JDK17 다운로드

JDK17 다운
또는,
Adoptium↗ 사이트에서 JDK 17을 다운로드하여 설치할 수 있습니다.
프로젝트가 열리면
build.gradle 파일의
dependencies 부분을 확인해 봅니다.
우리가 직접 추가하지 않았지만 기본적으로 들어있는 중요한 친구가 있습니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// 이 줄이 반드시 있는지 확인해주세요!
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
바로 spring-boot-starter-test입니다.
이 녀석은 우리가 별도로 추가하지 않아도 Spring Boot가 "너 이거 테스트할 때 꼭 필요할 거야"라며 자동으로 넣어줍니다.
여기에는
JUnit 5
,
AssertJ
,
Mockito
같은 핵심 도구들이 모두 포함되어 있습니다.
JUnit 5는 자바 개발자가 가장 많이 사용하는 테스트 도구입니다.
우리가 작성한 코드가 의도대로 동작하는지 확인해 주는 채점관 역할을 합니다.
테스트 코드에는 특별한 표시(어노테이션)를 붙여야 작동합니다.
가장 자주 사용하는 세 가지를 알아보겠습니다.
@Test
이 메서드가 테스트 대상임을 알립니다.
@BeforeEach
각 테스트 메서드가 실행되기 전
에 매번 실행됩니다.
@AfterEach
각 테스트 메서드가 실행된 후
에 매번 실행됩니다.
이 구조는 자료구조의
스택(Stack)
이나 알고리즘의
재귀 함수
실행 과정과 비슷합니다.
어떤 작업을 수행하기 전에 환경을 세팅하고(Push), 작업이 끝나면 원래대로 정리하는(Pop) 과정이 필요하기 때문입니다.
테스트 간에 서로 영향을 주지 않도록
독립성
을 보장하기 위해 사용합니다.
class StudyTest {
@BeforeEach
void setUp() {
System.out.println("테스트 준비");
}
@Test
void create() {
System.out.println("테스트 실행");
}
@AfterEach
void tearDown() {
System.out.println("테스트 정리");
}
}
🚀
AssertJ와 Mockito 기본 사용법 🔗
JUnit이 테스트를 실행해 준다면, AssertJ와 Mockito는 테스트의 내용을 채워주는 도구입니다.
과거에는 assertEquals(expected, actual) 같은 방식을 썼습니다.
하지만 순서가 헷갈리고 문장처럼 읽히지 않는 단점이 있었습니다.
AssertJ는 이를 개선하여 영어 문장을 쓰듯이 코드를 작성할 수 있게 해줍니다.
// AssertJ 사용 예시
assertThat(coffee.getPrice()).isEqualTo(4500);
assertThat(coffee.getName()).startsWith("Ice");
코드를 해석해 보면 "커피 가격이 4500원과 같은지 확인해라", "커피 이름이 Ice로 시작하는지 확인해라"처럼 자연스럽게 읽힙니다.
개발자가 아닌 사람이 봐도 이해할 수 있을 정도로 직관적입니다.
Mockito는 말 그대로
모조품(Mock)
을 만드는 도구입니다.
우리가 자동차 엔진을 테스트하고 싶은데, 자동차 바퀴나 핸들까지 모두 조립할 필요는 없습니다.
엔진 외의 부품은 가짜로 만들어 끼워두고 엔진 성능만 테스트하면 됩니다.
실제 개발에서도 데이터베이스나 외부 API 같은 무거운 기능들은 Mockito를 이용해 가짜로 대체하여 테스트합니다.
이에 대한 자세한 사용법은 이후 포스팅에서 구체적으로 다루겠습니다.
테스트 코드를 어디에 저장해야 할까요?
Java 프로젝트는 표준화된 디렉터리 구조를 따릅니다.
가장 중요한 원칙은
실제 코드와 동일한 패키지 구조
를 유지하는 것입니다.
- 실제 코드: src/main/java/com/example/demo/service/UserService.java
- 테스트 코드: src/test/java/com/example/demo/service/UserServiceTest.java

대칭 구조
이렇게 구조를 똑같이 맞추면 두 가지 장점이 있습니다.
찾기 쉽다
실제 코드를 보다가 테스트 코드가 필요하면 같은 경로로 이동하면 됩니다.
접근 제어
같은 패키지(default, protected) 내에 있는 클래스나 메서드에 접근할 수 있어 테스트하기 유리합니다.
IDE를 사용하면 이 구조를 자동으로 만들어줍니다.
테스트하고 싶은 클래스 이름을 클릭하고 단축키를 입력하면 됩니다.
Mac
Command + Shift + T
Windows/Linux
Ctrl + Shift + T
이 단축키를 누르면 "Create New Test" 창이 뜨면서 자동으로 적절한 위치에 테스트 파일을 생성해 줍니다.
개발 생산성을 위해 꼭 외워두시는 것이 좋습니다.
오늘은 TDD를 시작하기 위한 Spring Boot 환경 설정에 대해 알아보았습니다.
핵심 내용을 요약하면 다음과 같습니다.
프로젝트 설정
Spring Initializr에서 Gradle, Java 17, Spring Web을 선택하여 생성합니다.
도구 이해
JUnit 5(실행), AssertJ(검증), Mockito(가짜 객체)의 역할을 이해했습니다.
패키지 구조
src/main과 src/test의 패키지 구조를 데칼코마니처럼 동일하게 맞춥니다.
이제 도구 준비가 끝났습니다.
다음 시간에는 실제 요구사항을 분석하고 이를 테스트 코드로 옮기는 구체적인 방법을 다뤄보겠습니다.
이론보다는 실제 코드를 작성하는 재미있는 시간이 될 것입니다.
- Spring Boot 2.2 버전부터 JUnit 5가 기본으로 탑재되었습니다.
- AssertJ는 정적 임포트(static import)를 활용하면 코드를 훨씬 간결하게 작성할 수 있습니다.