1. Test Scope Dependencies
spring-boot-starter-test에 포함된 주요 라이브러리
라이브러리 | 설명 |
JUnit 5 |
Java 애플리케이션 단위 테스트의 표준 프레임워크
|
Spring Test & Spring Boot Test |
Spring Boot 애플리케이션을 위한 테스트 유틸리티 및 통합 테스트 지원
|
AssertJ |
직관적이고 유창한 API를 제공하는 assertion 라이브러리
|
Hamcrest |
matcher 객체(제약조건 또는 조건자)를 제공하는 라이브러리
|
Mockito | Java용 목(mock) 객체 생성 프레임워크 |
JSONassert |
JSON 형식 데이터를 위한 assertion 라이브러리
|
JsonPath | JSON 데이터를 위한 XPath 유사 쿼리 언어 |
Awaitility | 비동기 시스템을 테스트하기 위한 라이브러리 |
2. @SpringBootTest
- Spring Boot 애플리케이션 컨텍스트를 로드하여 통합 테스트를 가능하게 해주는 애노테이션
- @ContextConfiguration의 대안
- @ExtendWith(SpringExtension.class)가 포함되어 있음
- 실제 환경과 유사하게 통합 테스트하고 싶은 경우
옵션
webEnvironment
옵션 | 설명 |
MOCK (기본값) |
웹 ApplicationContext를 로드하되, 서블릿 컨테이너는 시작하지 않음 (Mock 환경에서 테스트)
- @AutoConfigureMockMvc 또는 @AutoConfigureWebTestClient와 함께 사용 |
RANDOM_PORT | 실제 내장 서버 시작, 랜덤 포트에서 실행됨 - @Transactional 시 롤백되지 않음 (클라이언트/서버가 다른 스레드) |
DEFINED_PORT |
실제 내장 서버 시작, 지정 포트(application.properties) 또는 기본 포트(8080) 사용
- @Transactional 시 롤백되지 않음 (클라이언트/서버가 다른 스레드) |
NONE | 웹 환경 없이 일반 ApplicationContext만 로드 |
예제) MOCK
더보기
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = org.example.Main.class)
@AutoConfigureMockMvc
public class WebEnvironmentMockTest {
@Autowired
private MockMvc mockMvc;
@Test
void testHello() throws Exception{
mockMvc.perform(get("/test/hello"))
.andExpect(status().isOk())
.andExpect(content().string("hello spring"));
}
}
2025-04-21T05:33:09.611+09:00 INFO 97099 --- [ Test worker] WebEnvironmentMockTest : Started WebEnvironmentMockTest in 3.118 seconds (process running for 4.144)
예제) RANDOM_PORT
더보기
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = org.example.Main.class)
public class WebEnvironmentRandomPortTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void testHello() {
String response = restTemplate.getForObject("http://localhost:"+port+"/test/hello", String.class);
assertEquals("hello spring", response);
}
}
2025-04-21T05:42:18.160+09:00 INFO 3278 --- [ Test worker] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 61220 (http) with context path ''
예제) DEFINED_PORT
더보기
# application-test.yml (/src/test/resources)
server:
port: 8085
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = org.example.Main.class)
@ActiveProfiles("test")
public class WebEnvironmentDefinedPortTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testHello() {
int port = 8085;
String response = restTemplate.getForObject("http://localhost:"+port+"/test/hello", String.class);
assertEquals("hello spring", response);
}
}
2025-04-21T05:45:19.136+09:00 INFO 5458 --- [ Test worker] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8085 (http) with context path ''
useMainMethod
실행 모드 | 설명 |
ALWAYS | 무조건 main() 메서드를 실행함 |
WHEN_AVAILABLE | main() 메서드가 있으면 실행하고, 없으면 실행하지 않음 |
NEVER (기본값) | main() 메서드를 절대 실행하지 않음 |
예제) ALWAYS
더보기
@SpringBootApplication
public class Main {
public static void main(String[] args) {
System.out.println("ALWAYS execute!");
SpringApplication app = new SpringApplication(Main.class);
app.run(args);
}
}
@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.ALWAYS, classes = org.example.Main.class)
public class UseMainMethodAlwaysTest {
@Test
void name() {
assertTrue(true);
}
}
ALWAYS execute! 출력 ✅
예제) NEVER
더보기
@SpringBootApplication
public class Main {
public static void main(String[] args) {
System.out.println("ALWAYS execute!");
SpringApplication app = new SpringApplication(Main.class);
app.run(args);
}
}
@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.NEVER, classes = org.example.Main.class)
public class UseMainMethodAlwaysTest {
@Test
void name() {
assertTrue(true);
}
}
ALWAYS execute! 출력 ❌
3. @TestConfiguration
- 테스트 전용 설정을 위한 클래스
- 테스트 환경에서만 활성화됨
- 중첩하여 사용할 수 있음
항목 | @Configuration |
@TestConfiguration
|
정의 위치 | 일반 애플리케이션 코드 | 테스트 코드 전용 |
역할 | Spring에서 애플리케이션의 Bean 설정을 정의 |
테스트에서만 사용할 설정 및 Bean 정의
|
컴포넌트 스캔 여부 | 기본적으로 컴포넌트 스캔 대상이 됨 |
테스트에서 자동으로 스캔되지 않음
(@SpringBootTest, @DataJpaTest 등) |
주요 용도 | 실제 어플리케이션의 설정 클래스 |
테스트 전용 Bean 구성 (Mock, Stub 등)
|
컨텍스트 통합 여부 | @ComponentScan 등에 의해 전체 Context에 포함 |
분리된 테스트 Context에서만 사용됨
|
예시) @TestConfiguration
더보기
1. 중첩
@SpringBootTest(classes = {org.example.Main.class, TestConfigurationTest.TestConfig.class})
public class TestConfigurationTest {
@Autowired
private TestService myService; // 실제 빈을 테스트할 대상
@TestConfiguration
static class TestConfig {
@Bean
public TestService myService() {
return mock(TestService.class); // 테스트용 서비스 빈
}
}
@Test
void testService() {
assertNotNull(myService); // 테스트 코드
}
}
2. @Import
@TestConfiguration
public class TestConfig {
@Bean
public TestService myService() {
return mock(TestService.class); // 테스트용 서비스 빈
}
}
@SpringBootTest(classes = org.example.Main.class)
@Import(TestConfig.class)
public class TestConfigurationTestWithImport {
@Autowired
private TestService myService; // 실제 빈을 테스트할 대상
@Test
void testService() {
assertNotNull(myService); // 테스트 코드
}
}
4. Slice Test
- 테스트 시 전체 애플리케이션을 로드하지 않고, 특정 레이어만 테스트할 수 있도록 다양한 @…Test 애노테이션을 제공
- 여러 슬라이스 테스트 애노테이션을 동시에 사용 불가 (@SpringBootTest + @AutoConfigure… 조합으로 대체)
- 슬라이스 테스트 (@WebMvcTest, @DataJpaTest 등)는 기본적으로 @Configuration 클래스는 스캔 안 함.
- 하지만 @Component는 스캔 대상이 됨.
종류
애노테이션 | 자동 구성 대상 | 목적 및 특징 | 기타 비고 |
@WebMvcTest | @Controller, @ControllerAdvice @JsonComponent Converter GenericConverter Filter HandlerInterceptor WebMvcConfigurer HandlerMethodArgumentResolver |
Spring MVC Web Layer 테스트 |
MockMvc와 함께 사용
|
@WebFluxTest | @Controller @ControllerAdvice (WebFlux) |
Reactive Web Layer 테스트 |
WebClient 테스트용
|
@DataJpaTest | JPA 관련 컴포넌트 | Repository, EntityManager 테스트 |
기본적으로 내장 H2 사용
기본적으로 트랜잭션이 적용됨 |
@DataJdbcTest | Spring Data JDBC | JDBC 기반 Repository 테스트 | - |
@DataMongoTest | MongoDB 관련 구성 | MongoRepository 테스트 | - |
@DataRedisTest | @RedisHash Spring Data Redis Repository |
Redis Repository 테스트 Spring Boot 2.4+부터 정식 지원 |
@Component, @ConfigurationProperties는 제외됨
|
@RestClientTest | @RestTemplateBuilder MockRestServiceServer |
REST 클라이언트 테스트 (외부 API Mocking) |
외부 HTTP 호출 테스트용
|
@JdbcTest | JDBC 관련 구성 | JDBC 테스트, 트랜잭션 포함 |
@DataJdbcTest보다 더 범용적으로 사용 가능
|
@JsonTest | ObjectMapper JsonComponent |
JSON 직렬화/역직렬화 테스트 |
Jackson 관련 테스트
|
예제) @WebMvcTest
더보기
@WebMvcTest(
controllers = TestController.class,
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = JsonComponent.class),
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "org\\.example\\..*Config"),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = jakarta.servlet.Filter.class) // 일반 필터
}
)
@ContextConfiguration(classes = Main.class)
public class ControllerSlicingTest {
@Autowired
private MockMvc mockMvc;
@Test
void testHello() throws Exception {
mockMvc.perform(get("/test/hello"))
.andExpect(status().isOk())
.andExpect(content().string("hello spring"));
}
}
예제) @DataJpaTest
더보기
@DataJpaTest
@TestPropertySource(locations = "classpath:application-test.yml")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(classes = Main.class)
public class MemberRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void testUserRepository() {
User user = new User("dummy user");
userRepository.save(user);
assertThat(userRepository.findByName("dummy user")).isNotNull();
}
}
@AutoConfigureTestDatabase
- 테스트 시, 기본 데이터베이스는 내장 H2로 지정됨
- 테스트 시 사용할 데이터베이스 설정을 셋팅할 수 있음
예제) @DataJdbcTest
더보기
@DataJdbcTest
@TestPropertySource(locations = "classpath:application-test.yml")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(classes = Main.class)
public class JdbcSlicingTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
void testUserTable() {
jdbcTemplate.update("INSERT INTO user(name) VALUES(?)", "dummy user");
User newUser = jdbcTemplate.queryForObject("SELECT * FROM user WHERE name='" + "dummy user" + "'", (rs, rowNum) -> {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
return user;
});
assertEquals(newUser.getName(), "dummy user");
}
}
예제) @DataMongoTest
예제) @DataRedisTest
예제) @RestClientTest
더보기
@Service
public class MyRestClient {
private final RestTemplate restTemplate;
public MyRestClient(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
public String getData() {
URI uri = UriComponentsBuilder.fromUriString("http://localhost:8080").path("/hello").encode().build().toUri();
return restTemplate.getForObject(uri, String.class);
}
}
@RestClientTest(MyRestClient.class)
@ContextConfiguration(classes = Main.class)
public class RestSlicingTest {
@Autowired
private MyRestClient myRestClient;
@Autowired
private MockRestServiceServer mockServer;
@Test
void testRestClient() {
mockServer.expect(requestTo("http://localhost:8080/hello")).andRespond(withSuccess("Mocked Response", MediaType.TEXT_PLAIN));
assertThat(myRestClient.getData()).isEqualTo("Mocked Response");
mockServer.verify();
}
}
MockRestServiceServer
- RestTemplate 또는 RestClient의 HTTP 요청을 가로채서 모의 응답을 반환합니다.
- 실제 네트워크 통신 없이 메모리 내에서 모든 처리가 완료됩니다.
예제) @JsonTest
더보기
@JsonTest
@ContextConfiguration(classes = Main.class)
public class JsonSlicingTest {
@Autowired
private JacksonTester<User> json;
@Test
void testJsonSerialization() throws IOException {
String content = "{\"name\":\"json\"}";
assertThat(json.parseObject(content).getName()).isEqualTo("json");
}
}
Auto-Configuration 추가하기
방법 | 적용 방식 | 적용 범위 |
@ImportAutoConfiguration | 테스트 클래스에서 직접 어노테이션 사용 (해당 테스트 클래스에만 적용) |
@ImportAutoConfiguration 을 써야 Auto-Configuration이 적용됨. (@Import ❌) |
META-INF/spring/*.imports | 리소스 파일에 클래스명 명시 (프로젝트 내 모든 해당 슬라이스 테스트에 전역 적용) |
프로젝트 전체에 일괄 적용 관리가 쉽고, 일관성 유지 용이 |
예제) MyJdbcTest
더보기
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
class MyJdbcTests {
}
예제) META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.JdbcTest.imports
더보기
com.example.IntegrationAutoConfiguration
출처
'Spring > Spring Boot' 카테고리의 다른 글
[Spring Boot] 5. Executable Jars (0) | 2023.10.13 |
---|---|
[Spring Boot] 4. Data: SQL Databases (0) | 2023.10.13 |
[Spring Boot] 3. Web: Servlet Web Application (0) | 2023.10.12 |
[Spring Boot] 2-10. Core Features: Auto-Configuration (0) | 2023.10.11 |
[Spring Boot] 2-6. Core Features: JSON (0) | 2023.10.09 |