반응형
Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- junit
- java테스트
- input
- 이클립스
- 단위테스트
- 배열
- 자바스크립트
- 자바
- string
- HashMap
- IntelliJ
- html
- javascript
- CSS
- 인텔리제이
- list
- js
- Java
- 문자열
- 자바문법
- 테스트자동화
- junit5
- Eclipse
- ArrayList
- Array
- json
- math
- Visual Studio Code
- 정규식
- vscode
Archives
- Today
- Total
어제 오늘 내일
[JUnit] @Nested를 이용한 테스트 코드 구조화 패턴 본문
1. @Nested
@Nested는 JUnit 5에서 테스트 코드를 논리적으로 그룹화하기 위해 제공되는 애너테이션입니다.
한 클래스 안에서 상황(조건)별로 테스트를 묶을 수 있어서, 테스트가 많아져도 구조를 명확하게 유지할 수 있습니다.
주요 특징입니다.
- 외부 테스트 클래스 안에 내부 클래스를 만들어 그룹을 나눕니다.
- 각 내부 클래스에 @Nested를 붙여 **“이 상황에서의 테스트 묶음”**을 표현합니다.
- @DisplayName과 함께 사용하면 테스트가 문서처럼 읽힙니다.
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
class UserServiceTest {
@Nested
class 회원가입_기능 {
@Test
void 정상_회원가입() {
// 검증 코드
}
@Test
void 중복_아이디로_실패() {
// 검증 코드
}
}
}
2. 상태/상황별로 테스트를 그룹화하는 기본 패턴
아래 예제는 계좌(Account)의 상태에 따라 테스트를 나누는 패턴입니다.
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AccountTest {
@Nested
class 잔액이_0원인_상태 {
@Test
void 출금하면_실패합니다() {
int balance = 0;
int withdraw = 100;
assertTrue(withdraw > balance);
}
@Test
void 입금하면_잔액이_증가합니다() {
int balance = 0;
int deposit = 100;
assertEquals(100, balance + deposit);
}
}
@Nested
class 잔액이_양수인_상태 {
@Test
void 출금하면_잔액이_감소합니다() {
int balance = 1000;
int withdraw = 200;
assertEquals(800, balance - withdraw);
}
}
}
설명
- “잔액이 0원인 상태”, “잔액이 양수인 상태”처럼 상태 기준으로 그룹을 나눕니다.
- 각 그룹 안에는 그 상태에서 가능한 행동/결과에 대한 테스트가 모여 있습니다.
- 테스트를 읽는 것만으로 도메인 규칙을 이해하기 쉬워집니다.
3. @BeforeEach와 함께 사용하는 패턴
내부 클래스마다 공통 준비 코드를 둘 수도 있습니다.
상황별로 다른 초기 상태를 만들 때 유용합니다.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class BankAccountTest {
static class BankAccount {
private int balance;
BankAccount(int balance) {
this.balance = balance;
}
void deposit(int amount) {
balance += amount;
}
void withdraw(int amount) {
balance -= amount;
}
int getBalance() {
return balance;
}
}
@Nested
class 초기_잔액이_1000원인_계좌 {
BankAccount account;
@BeforeEach
void setUp() {
account = new BankAccount(1000);
}
@Test
void 입금하면_잔액이_증가합니다() {
account.deposit(500);
assertEquals(1500, account.getBalance());
}
@Test
void 출금하면_잔액이_감소합니다() {
account.withdraw(300);
assertEquals(700, account.getBalance());
}
}
@Nested
class 초기_잔액이_0원인_계좌 {
BankAccount account;
@BeforeEach
void setUp() {
account = new BankAccount(0);
}
@Test
void 출금하면_마이너스가_됩니다() {
account.withdraw(100);
assertEquals(-100, account.getBalance());
}
}
}
설명
- 각 @Nested 클래스 안에 @BeforeEach를 두어 그 그룹만의 초기 상태를 만듭니다.
- 같은 BankAccount라도 “초기 잔액이 1000원”, “초기 잔액이 0원”을 분리해서 더 명확하게 표현합니다.
4. @DisplayName과 함께 테스트를 문서처럼 만들기
@Nested와 @DisplayName을 같이 사용하면 테스트 결과를 시나리오 문서처럼 읽을 수 있습니다.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("회원 서비스 테스트")
class UserServiceTest {
@Nested
@DisplayName("회원가입 기능")
class SignUpTests {
@Test
@DisplayName("정상 정보로 회원가입에 성공한다")
void signUp_success() {
boolean result = true;
assertTrue(result);
}
@Test
@DisplayName("이미 존재하는 아이디로는 회원가입에 실패한다")
void signUp_fail_when_duplicate_id() {
boolean result = false;
assertFalse(result);
}
}
@Nested
@DisplayName("로그인 기능")
class LoginTests {
@Test
@DisplayName("올바른 아이디와 비밀번호로 로그인에 성공한다")
void login_success() {
boolean result = true;
assertTrue(result);
}
}
}
설명
- 실행 결과에
- “회원 서비스 테스트 > 회원가입 기능 > 정상 정보로 회원가입에 성공한다”
같은 형태로 표시되어, 테스트가 설명서처럼 읽히는 구조가 됩니다.
- “회원 서비스 테스트 > 회원가입 기능 > 정상 정보로 회원가입에 성공한다”
5. @Nested 사용 시 패턴과 팁
- 상태·상황 기준으로 나눈다
“로그인된 상태”, “로그인되지 않은 상태”, “재고가 있는 상품”, “재고가 없는 상품”처럼
도메인에서 중요한 상태를 기준으로 @Nested 클래스를 나누면 이해하기 쉽습니다. - 테스트 메소드 이름은 짧게, @DisplayName은 설명형으로
- 메소드: login_success()
- DisplayName: "올바른 아이디와 비밀번호로 로그인에 성공한다"
와 같이 분리하면 코드와 문서 역할을 나눌 수 있습니다.
- 중첩 깊이를 너무 깊게 만들지 않는다
2~3단계를 넘기면 오히려 복잡해질 수 있으므로, 상위 수준의 구조만 @Nested로 표현하는 것이 좋습니다. - 공통 준비 코드는 각 @Nested 클래스 내부에 둔다
상황마다 초기 상태가 다르므로, @BeforeEach를 각 내부 클래스에서 정의하면 테스트가 서로 영향을 주지 않습니다.
6. 정리
@Nested는 테스트를 상황·상태별로 구조화할 수 있게 해 주는 기능입니다.
@BeforeEach, @DisplayName과 함께 사용하면 테스트 코드가
- 읽기 쉽고
- 유지보수하기 좋고
- 도메인 규칙을 그대로 드러내는
문서 같은 테스트로 바뀝니다.
반응형
'IT > JUnit' 카테고리의 다른 글
| [JUnit] @BeforeAll – 테스트 시작 전 한 번만 수행되는 작업 (0) | 2026.01.10 |
|---|---|
| [JUnit] setUp() & tearDown() - 테스트 준비와 정리 단계 이해하기 (0) | 2026.01.09 |
| [JUnit] @DisplayName으로 테스트를 문서처럼 읽기 좋게 만드는 방법 (0) | 2026.01.08 |
| [JUnit] @BeforeEach, @AfterEach로 테스트 공통 준비 코드 관리하기 (0) | 2026.01.08 |
| [JUnit] assertAll을 활용한 DTO/엔티티 필드 일괄 검증 (0) | 2026.01.07 |
Comments
