Given-When-Then 패턴이란?
- 테스트 코드를 일련의 이야기로 읽게 만드는 구조
- BDD (Behavior Driven Development)에서 파생된 개념
- 실무에서는 단위 테스트 작성 시에도 광범위하게 사용됨
- Given (준비) : "~한 상황이 주어졌을 때"
테스트에 필요한 사전 조건과 데이터 준비
- When (실행) : "~를 하면"
실제로 테스트하려는 동작 실행
- Then (검증) : "~한 결과가 나와야 한다"
실행 결과가 기대한 대로 나왔는지 검증
- SpringBoot / Junit 사용 기준으로 작성
@Test
@DisplayName("새로운 사용자를 생성할 수 있다")
void createNewUser() {
String name = "홍길동";
String email = "hgildong@example.com";
String password = "password123";
UserCreateDto createDto = new UserCreateDto(name, email, password);
UserResponseDto result = userService.createUser(createDto);
assertThat(result.getName()).isEqualTo(name);
assertThat(result.getEmail()).isEqualTo(email);
assertThat(result.getId()).isNotNull();
}
테스트 계층 구조
- Repository 테스트 - 데이터베이스 CRUD 로직
- Service 테스트 - 비즈니스 로직
- Controller 테스트 - API 엔드포인트
기타 팁
- @DisplayName 활용 : 주석처럼 테스트 의도를 명확하게 표현할것
- 테스트 격리 : 각 테스트는 독립적이야 함. @BeforeEach로 초기화하거나 @Transactional로 롤백할 것
- 단위(Unit) 테스트 70% / 통합(Integration)테스트 20% / E2E(End-to-End)테스트 10%
- 테스트용 Builder패턴이나 Fixture를 활용할 것
public class UserFixture {
public static User createDefaultUser() {
return User.builder()
.name("테스트유저")
.email("test@example.com")
.build();
}
public static User createUserWithEmail(String email) {
return User.builder()
.name("테스트유저")
.email(email)
.build();
}
}
결론
- 테스트는 설계 목적, 원하는 결과 설정이 명확해야 함
- 상황과 필요에 따라 테스트의 범위와 크기를 가변적으로 조정할 것