HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/
Spring
Spring
/
🎧
Spring Framework 핵심개념(Core)
/
📹
Spring TestContext Framework
📹

Spring TestContext Framework

@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

[참고] https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testcontext-ctx-management-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 (from ContextCustomizerFactory) – 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)