@SpringJuintConfig value, classes field( 똑같은듯함)@SpringJuintConfig - initializer field소개사용법@ContextConfiguration@ActiveProfiles@SpringJunitConfig@SpringJuintConfig value, classes field( 똑같은듯함)@SpringJuintConfig - initializer fieldContext ManagementContext Caching
@SpringJuintConfig value, classes field( 똑같은듯함)
- 해당 field에 @Configuration으로 쓸 클래스를 명시함. <ClassName>.class 와 같이
@SpringJuintConfig - initializer field
- application context를 initialize할 때의 동작을 커스텀하게 명시할 수 있음
public class TestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { var config = aMysqldConfig(v8_0_11) .withCharset(UTF8) .withPort(2215) .withUser("test-user", "test111!") .withTimeZone("Asia/Seoul") .build(); anEmbeddedMysql(config) .addSchema("order_mgmt", classPathScript("schema.sql")) .start(); } } @SpringJUnitConfig(value = TestConfig.class, initializers = TestContextInitializer.class)
소개
- 테스트를 할 때 Mockito를 이용해서 테스트를 수행할 수도 있고, Spring에서 지원하는 Mock객체를 이용하여 테스트를 구성할 수도 있음
- Integration Testing에서 Spring Framework가 다양한 기능들을 지원해 주는데 Spring TestContext Framework에서는 테스트 클래스에 하나의 Annotation(@SpringJUnitConfig)을 붙임으로써 ApplicationContext를 활용할 수 있게 해줌
- ApplicationContext에서 캐쉬 기능이 되어서 같은 내용의 Container면 캐쉬를 이용해서 container 만드는 것이 조금은 빨라짐
- 아래에 소개되는 사용들은 Mock을 전달하는 것이 아닌 실제 객체를 이용한 것임(Autowire로) ⇒ Integration test임
사용법
- @ContextConfiguration , @ExtendWith(SpringExtension.class) 를 활용하여 spring IoC container를 활용할 수 있음. Autowire 가능해짐
- junit5에서 동작하기 위해서 ExtendWith을 통해 SpringExtension.class를 하게 되면 실제 TestContextFramework을 사용할 수 있게 해줌
@ExtendWith(SpringExtension.class) @ContextConfiguration public class KdtSpringContextTests { @Autowired ApplicationContext context; @Test @DisplayName("applicationContext가 생성 되어야 함") public void testApplicationContext(){ assertThat(context, notNullValue()); } }
@ContextConfiguration
- 해당 테스트 클래스에서 가져올 Configuration을 지정해 줄 수 있는 Annotation임
- 지정이 안되어 있으면 default로 해당 테스트 클래스 안에서 static으로 선언된 Configuration annotation 붙은 클래스를 찾게 됨
@ActiveProfiles
- 테스트 환경에서 어떤 profile을 쓸 지 명시해 줄 수 있음
@SpringJunitConfig
- 위의 @ContextConfiguration과 @ExtendWith을 합친 annotation임. Spring에서 Junit과 같이 상호 작용하기 위해서 만든 annotation임
- @ContextConfiguration이 포함되어 있기에 내부에 있는 static class Config(@Configuration)을 이용하여 configuration을 진행하고 bean 등록함
- 테스트 클래스에 붙이는 어노테이션으로 해당 어노테이션을 붙이면 Spring의 bean들을 Junit Test시에 Autowire 가능하게 해줌! — Spring Integration test
- 이 어노테이션을 한번 더 감싼 것이 @SpringBootTest — spring boot application에 대한 통합 테스트
@SpringJUnitConfig @ContextConfiguration public class KdtSpringContextTests { @Configuration @ComponentScan({"org.prgms.order", "org.prgms.voucher"}) static class Config{ } @Autowired ApplicationContext context; @Autowired OrderService orderService; @Autowired VoucherRepository voucherRepository; @Test @DisplayName("applicationContext가 생성 되어야 함") public void testApplicationContext(){ assertThat(context, notNullValue()); } @Test @DisplayName("VoucherRepository가 빈으로 등록되어 있어야 한다.") public void testVoucherRepositoryCreation(){ var bean = context.getBean(VoucherRepository.class); assertThat(bean, notNullValue()); } @Test @DisplayName("orderService를 사용해서 주문을 생성할 수 있다.") void testOrderService() { Voucher fixedAmountVoucher = new FixedAmountVoucher(UUID.randomUUID(), 100L); voucherRepository.insert(fixedAmountVoucher); System.out.println(voucherRepository.getClass().getName()); var order = orderService.createOrder( UUID.randomUUID(), List.of(new OrderItem(UUID.randomUUID(), 200, 1)), fixedAmountVoucher.getVoucherId()); assertThat(order.totalAmount(), is(100L)); assertThat(order.getVoucher().isEmpty(), is(false)); assertThat(order.getVoucher().get().getVoucherId(), is(fixedAmountVoucher.getVoucherId())); assertThat(order.getOrderStatus(), is(OrderStatus.ACCEPTED)); } }
@SpringJuintConfig value, classes field( 똑같은듯함)
- 해당 field에 @Configuration으로 쓸 클래스를 명시함. <ClassName>.class 와 같이
@SpringJuintConfig - initializer field
- application context를 initialize할 때의 동작을 커스텀하게 명시할 수 있음
public class TestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { var config = aMysqldConfig(v8_0_11) .withCharset(UTF8) .withPort(2215) .withUser("test-user", "test111!") .withTimeZone("Asia/Seoul") .build(); anEmbeddedMysql(config) .addSchema("order_mgmt", classPathScript("schema.sql")) .start(); } } @SpringJUnitConfig(value = TestConfig.class, initializers = TestContextInitializer.class)
Context Management
Context Caching
- TestContext 프레임워크에서 ApplicationContext나 WebApplicationContext를 로드하고 나면 context는 캐쉬되어서 계속 재사용 됨
- ApplicaitonContext는 configuration parameter의 조합으로 유일하게 식별됨
- The TestContext framework uses the following configuration parameters to build the context cache key:
locations
(from@ContextConfiguration
)classes
(from@ContextConfiguration
)contextInitializerClasses
(from@ContextConfiguration
)contextCustomizers
(fromContextCustomizerFactory
) – this includes@DynamicPropertySource
methods as well as various features from Spring Boot’s testing support such as@MockBean
and@SpyBean
.contextLoader
(from@ContextConfiguration
)parent
(from@ContextHierarchy
)activeProfiles
(from@ActiveProfiles
)propertySourceLocations
(from@TestPropertySource
)propertySourceProperties
(from@TestPropertySource
)resourceBasePath
(from@WebAppConfiguration
)