SpringBoot에서 테스트 시작하기
Spring Boot는 애플리케이션을 테스트하기 위한 많은 기능을 제공해 줍니다!
Spring boot에서 테스트 모듈은 spring-boot-test와 spring-boot-test-autoconfigure가 존재하는데,
대부분의 경우는 spring-boot-starter-test만으로도 충분하며, spring-boot-starter-test는 spring boot의 테스트에 사용되는 Starter 패키지입니다.
spring-boot-starter-test는 JUnit는 물론이고, AssertJ, Hamcrest를 포함한 여러 유용한 라이브러리를 포함하고 있습니다.
spring-boot-starter-test를 대부분 사용하면 테스트를 위한 라이브러리 외에도 여러 유용한 라이브러리를 포함하고 있습니다.
- JUnit
- Spring Test & Spring Boot Test
- AssertJ
- Hamcrest
- Mockito
- JSONassert
- JsonPath
@SpringBootTest
spring-boot-test는 @SpringBootTest라는 에노테이션을 제공하고 있습니다.
@SpringBootTest 에노테이션은 테스트에 사용할 Application Context를 쉽게 생성 및 조작할 수 있으며, 이는 기존 spring-test에서 사용하던 @ContextConfiguration의 발전된 기능입니다.
이러한 @SpringBootTest는 매우 다양한 기능을 제공합니다!
전체 빈 중 특정 빈을 선택하여 생성한다든지, 특정 빈을 Mock으로 대체한다든지, 테스트에 사용할 프로퍼티 파일을 선택하거나 특정 속성만 추가한다든지, 특정 Configuration을 선택하여 설정할 수도 있습니다.
또한, 주요 기능으로 테스트 웹 환경을 자동으로 설정해주는 기능이 있습니다.
또한 Junit5 에 들어와서 부터는 @RunWith(SpringRunner.class) 를 사용하지 않아도 됩니다!
1. @SpringBootTest는 통합테스트를 위해 주로 사용한다!
1) 개요
- 실제 운영 환경에서 사용될 클래스들을 통합하여 테스트 하는것을 통합테스트라 부른다.
- 단위 테스트와 같이 기능 검증을 위한 것이 아니라 spring framework에서 전체적으로 플로우가 제대로 동작하는지 검증하기 위해 사용
2) 장점
- 애플리케이션의 설정, 모든 Bean을 모두 로드하기 때문에 운영환경과 가장 유사한 테스트가 가능하다.
- 전체적인 Flow를 쉽게 테스트 가능하다.
3) 단점
- 애플리케이션의 설정, 모든 Bean을 모두 로드하기 때문에 시간이 오래걸리고 무겁다.
- 테스트 단위가 크기 때문에 디버깅이 어려운 편이다.
2. 제공되는 기능
- 전체 빈들 중 특정 빈을 선택하여 생성
- 특정 빈을 Mock으로 대체
- 테스트에 사용할 프로퍼티 파일을 선택하거나 특정 속성만 추가
- 특정 Configuration을 선택하여 설정
- 테스트 웹 환경을 자동으로 설정
1) Bean
@SpringBootTest 어노테이션은 classes라는 속성을 제공합니다. 해당 속성을 통해서 빈을 생성할 클래스들을 지정할 수 있습니다.
classes 속성에 @Configuration 어노테이션을 사용하는 클래스가 있다면 내부에서 @Bean 어노테이션을 통해서 생성되는 빈도 모두 등록이 됩니다.
만일 classes 속성을 통해서 클래스를 지정하지 않으면 애플리케이션 상에 정의된 모든 빈을 생성합니다.
@SpringBootTest(classes = {UserServiceImpl.class, AutoConfig.class})
public class SpingBootTestV1 {
// Service로 등록하는 빈
@Autowired private UserServiceImpl userServiceImpl;
// AutoConfig에서 생성하는 빈
@Autowired private RestTemplate restTemplate;
}
2) TestConfiguration
기존에 정의했던 Configuration을 커스터마이징하고 싶은 경우 TestConfiguration 기능을 사용할 수 있습니다!
TestConfiguration은 ComponentScan 과정에서 생성될 것이며, 자신이 속한 테스트가 실행될때 정의된 빈을 생성하여 등록됩니다.
@SpringBootTest
class ConfigTest {
@Autowired
Dog dog;
@Test
void name() {
assertThat(dog.show()).isEqualTo("Test에서 만든 Dog 월 월!!");
}
@TestConfiguration
public static class TestConfig {
public TestConfig() {
System.out.println("TestConfig 생성");
}
// Config의 Dog빈을 커스터마이징한다.
@Bean
public Dog testDog() {
return new Dog("Test에서 만든 Dog");
}
}
}
ComponentScan을 통해서 감지되기 때문에 만일 @SpringBootTest의 classes 속성을 이용하여 특정 클래스만을 지정했을 경우에는 TestConfiguation은 감지되지 않습니다.
그런 경우 classes 속성에 직접 TestConfiguration을 추가하면 됩니다!
하지만 더 좋은 방법은 @Import 어노테이션을 사용하는 것입니다.
@Import 어노테이션을 통해서 직접 사용할 TestConfiguration을 명시할 수 있으며, 특정 테스트 클래스의 내부 클래스가 아닌 별도의 클래스로 분리하여 여러 테스트에서 공유할 수도 있습니다.
@SpringBootTest(classes = {Config.class})
@Import(TestConfig.class)
class ConfigTest {
@Autowired
Dog dog;
@Test
void name() {
assertThat(dog.show()).isEqualTo("Test에서 만든 Dog 월 월!!");
}
}
@TestConfiguration
public class TestConfig {
public TestConfig() {
System.out.println("TestConfig 생성");
}
// Config의 Dog빈을 커스터마이징한다.
@Bean
public Dog testDog() {
return new Dog("Test에서 만든 Dog");
}
}
3) MockBean
@MockBean을 사용하면 Mock 객체를 빈으로 등록할 수 있으며, @Autowired를 통해 빈을 주입시 Spring의 ApplicationContext는 Mock 객체를 주입해 줍니다!
만약 @MockBean으로 선언한 객체와 같은 이름과 티입으로 이미 빈 등록이되어있다면 선언한 Mock 빈으로 대체된다.
@SpringBootTest
public class MockBeanTest {
@MockBean
private Dog mockDog;
@Test
public void mockTest() {
// given
System.out.println(mockDog.getName());
// when
given(mockDog.getName()).willReturn("mockDog");
// then
System.out.println(mockDog.getName());
}
}
출력 결과는 다음과 같다
null
mockDog
처음 apple을 출력하면 MockBean으로 생성된 mockDog의 Name인 null을 반환한다.
이후 Mockito의 given - willReturn을 통해 Mock 객체가 리턴할 Name을 설정해준다.
mockDog의 Name이 설정된 Name으로 출력되는 것을 확인할 수 있다.
4. Properties
Spring Boot는 기본적으로 application.properties(혹은 application.yml)를 통해 애플리케이션 설정을 수행한다.
하지만 테스트 중 설정이 기존과 달라질 필요가 있는 경우, SpringBootTest의 properties라는 속성을 이용한다.
@SpringBootTest(properties = "classpath:application-test.yml")
public class SomeTest {
...
}
5. Web Environment
@SpringBootTest의 webEnvironment 파라미터를 이용해서 손쉽게 웹 테스트 환경을 선택할 수 있습니다. 제공하는 설정값은 아래와 같습니다.
- MOCK
- WebApplicationContext를 로드하며 내장된 서블릿 컨테이너가 아닌 Mock 서블릿을 제공.
- @AutoConfigureMockMvc 어노테이션을 함께 사용하면 별다른 설정 없이 간편하게 MockMvc를 사용한 테스트를 진행할 수 있습니다.
- @AutoConfigureMockMvc
Mock 테스트 시 필요한 의존성을 제공해 준다.
MockMvc 객체를 통해 실제 컨테이너가 실행되는 것은 아니지만 로직상 테스트를 진행할 수 있다.
(DispatcherServlet을 로딩하여 Mockup으로 처리가능)
- RANDOM_PORT
- EmbeddedWebApplicationContext를 로드하며 실제 서블릿 환경을 구성합니다.
- 생성된 서블릿 컨테이너는 임의의 포트를 listen
- DEFINED_PORT
- RAMDOM_PORT와 동일하게 실제 서블릿 환경을 구성하지만, 포트는 애플리케이션 프로퍼티에서 지정한 포트를 listen합니다(application.properties 또는 application.yml에서 지정한 포트).
- NONE
- 일반적인 ApplicationContext를 로드하며 아무런 서블릿 환경을 구성하지 않습니다.
출처
https://meetup.toast.com/posts/124
'BackEnd > Spring' 카테고리의 다른 글
[Spring] Thymeleaf 에러(Error resolving template) (0) | 2022.03.19 |
---|---|
[Spring] Transaction 동작 원리 (@Transactional 원리) (0) | 2022.03.09 |
[Spring] 빈 스코프 (0) | 2022.02.08 |
[Spring] 빈 생명주기 콜백 (0) | 2022.02.07 |
[Spring] 의존관계 자동 주입 (0) | 2022.02.05 |
댓글