Loading...
Spring Framework Reference Documentation 7.0.2의 TestContext Framework Support Classes의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
이 섹션에서는 JUnit 및 TestNG에서 Spring TestContext Framework를 지원하는 다양한 클래스에 대해 설명합니다.
SpringExtension은 Spring TestContext Framework를 JUnit Jupiter testing 프레임워크에 통합합니다.
Spring Framework 7.0부터
SpringExtension은 JUnit Jupiter 6.0 이상이 필요합니다.
테스트 클래스에 @ExtendWith(SpringExtension.class)를 어노테이션으로 선언하면 표준 JUnit Jupiter 기반 단위 및 통합 테스트를 구현하는 동시에 애플리케이션 컨텍스트 로딩, 테스트 인스턴스에 대한 의존성 주입, 트랜잭션 테스트 메서드 실행 등의 TestContext framework의 이점을 누릴 수 있습니다.
또한, JUnit Jupiter의 풍부한 extension API 덕분에, Spring은 JUnit 4 및 TestNG에 대해 Spring이 지원하는 기능 집합을 넘어서는 다음과 같은 기능을 제공합니다.
SpringExtension를 참조하십시오.@EnabledIf 및 @DisabledIf에 대한 문서를 참조하십시오.@TransactionalDevTestConfig 및 @TransactionalIntegrationTest 예제를 참조하십시오.다음 코드 목록은 @ContextConfiguration과 함께 SpringExtension을 사용하도록 테스트 클래스를 구성하는 방법을 보여줍니다.
1// Instructs JUnit Jupiter to extend the test with Spring support. 2@ExtendWith(SpringExtension.class) 3// Instructs Spring to load an ApplicationContext from TestConfig.class 4@ContextConfiguration(classes = TestConfig.class) 5class SimpleTests { 6 7 @Test 8 void testMethod() { 9 // test logic... 10 } 11}
1// Instructs JUnit Jupiter to extend the test with Spring support. 2@ExtendWith(SpringExtension::class) 3// Instructs Spring to load an ApplicationContext from TestConfig::class 4@ContextConfiguration(classes = [TestConfig::class]) 5class SimpleTests { 6 7 @Test 8 fun testMethod() { 9 // test logic... 10 } 11}
JUnit Jupiter에서 어노테이션을 메타어노테이션으로도 사용할 수 있으므로, Spring은 테스트 ApplicationContext와 JUnit Jupiter의 구성을 단순화하기 위해 @SpringJUnitConfig 및 @SpringJUnitWebConfig composed 어노테이션을 제공합니다.
다음 예제는 이전 예제에서 사용된 설정의 양을 줄이기 위해 @SpringJUnitConfig를 사용합니다.
1// Instructs Spring to register the SpringExtension with JUnit 2// Jupiter and load an ApplicationContext from TestConfig.class 3@SpringJUnitConfig(TestConfig.class) 4class SimpleTests { 5 6 @Test 7 void testMethod() { 8 // test logic... 9 } 10}
1// Instructs Spring to register the SpringExtension with JUnit 2// Jupiter and load an ApplicationContext from TestConfig.class 3@SpringJUnitConfig(TestConfig::class) 4class SimpleTests { 5 6 @Test 7 fun testMethod() { 8 // test logic... 9 } 10}
마찬가지로, 다음 예제는 JUnit Jupiter에서 사용할 WebApplicationContext를 생성하기 위해 @SpringJUnitWebConfig를 사용합니다.
1// Instructs Spring to register the SpringExtension with JUnit 2// Jupiter and load a WebApplicationContext from TestWebConfig.class 3@SpringJUnitWebConfig(TestWebConfig.class) 4class SimpleWebTests { 5 6 @Test 7 void testMethod() { 8 // test logic... 9 } 10}
1// Instructs Spring to register the SpringExtension with JUnit 2// Jupiter and load a WebApplicationContext from TestWebConfig::class 3@SpringJUnitWebConfig(TestWebConfig::class) 4class SimpleWebTests { 5 6 @Test 7 fun testMethod() { 8 // test logic... 9 } 10}
자세한 내용은 Spring JUnit Jupiter Testing Annotations의 @SpringJUnitConfig 및 @SpringJUnitWebConfig에 대한 문서를 참조하십시오.
SpringExtensionSpringExtension은 JUnit Jupiter의 ParameterResolver extension API를 구현하여, Spring이 테스트 생성자, 테스트 메서드 및 테스트 라이프사이클 콜백 메서드에 대해 의존성 주입을 제공할 수 있게 합니다.
구체적으로, SpringExtension은 테스트의 ApplicationContext로부터 Spring의 @BeforeTransaction 및 @AfterTransaction 또는 JUnit의 @BeforeAll, @AfterAll, @BeforeEach, @AfterEach, @Test, @RepeatedTest, @ParameterizedTest 등으로 어노테이션된 테스트 생성자 및 메서드에 의존성을 주입할 수 있습니다.
JUnit Jupiter 테스트 클래스의 생성자에서 특정 매개변수의 타입이 ApplicationContext(또는 그 하위 타입)이고 또는 @Autowired, @Qualifier, @Value로 어노테이션 또는 메타어노테이션되어 있으면, Spring은 해당 매개변수에 대해 테스트의 ApplicationContext로부터 해당 빈 또는 값을 주입합니다.
또한, 생성자가 _autowirable_로 간주되는 경우 테스트 클래스 생성자의 모든 인자를 자동 주입하도록 Spring을 구성할 수 있습니다. 생성자는 다음 조건 중 하나를(우선순위 순으로) 만족하는 경우 autowirable로 간주됩니다.
@Autowired로 어노테이션되어 있는 경우.@TestConstructor가 테스트 클래스에 autowireMode 속성이 ALL로 설정된 상태로 present 또는 meta-present인 경우.ALL로 변경된 경우.@TestConstructor의 사용 방법 및 전역 _테스트 생성자 자동 주입 모드_를 변경하는 방법에 대한 자세한 내용은 @TestConstructor를 참조하십시오.
테스트 클래스의 생성자가 _autowirable_로 간주되는 경우, Spring은 생성자의 모든 매개변수에 대한 인자를 resolve하는 책임을 집니다. 결과적으로, JUnit Jupiter에 등록된 다른 어떤
ParameterResolver도 이러한 생성자에 대한 매개변수를 resolve할 수 없습니다.
테스트 클래스에 대한 생성자 주입은
@DirtiesContext가 테스트의ApplicationContext를 테스트 메서드 전후에 close하는 데 사용되는 경우 JUnit Jupiter의@TestInstance(PER_CLASS)지원과 함께 사용되어서는 안 됩니다. 그 이유는@TestInstance(PER_CLASS)가 JUnit Jupiter에 테스트 메서드 호출 사이에 테스트 인스턴스를 cache하도록 지시하기 때문입니다. 결과적으로, 테스트 인스턴스는 이후에 close된ApplicationContext에서 원래 주입되었던 빈에 대한 참조를 유지하게 됩니다. 이러한 시나리오에서는 테스트 클래스의 생성자가 한 번만 호출되므로 의존성 주입이 다시 발생하지 않으며, 이후의 테스트는 close된ApplicationContext의 빈과 상호 작용하게 되어 오류가 발생할 수 있습니다.@TestInstance(PER_CLASS)와 함께 "before test method" 또는 "after test method" 모드에서@DirtiesContext를 사용하려면, 테스트 메서드 호출 사이에 다시 주입될 수 있도록 Spring에서 제공되는 의존성을 필드 또는 setter 주입을 통해 공급되도록 구성해야 합니다.
다음 예제에서 Spring은 TestConfig.class에서 로드된 ApplicationContext로부터 OrderService 빈을 OrderServiceIntegrationTests 생성자에 주입합니다.
1@SpringJUnitConfig(TestConfig.class) 2class OrderServiceIntegrationTests { 3 4 private final OrderService orderService; 5 6 @Autowired 7 OrderServiceIntegrationTests(OrderService orderService) { 8 this.orderService = orderService; 9 } 10 11 // tests that use the injected OrderService 12}
1@SpringJUnitConfig(TestConfig::class) 2class OrderServiceIntegrationTests @Autowired constructor( 3 private val orderService: OrderService 4) { 5 // tests that use the injected OrderService 6}
이 기능을 사용하면 테스트 의존성을 final로 선언하여 변경 불가능하게 만들 수 있습니다.
spring.test.constructor.autowire.mode 프로퍼티가 all로 설정되어 있는 경우(자세한 내용은 @TestConstructor 참조), 이전 예제에서 생성자에 대한 @Autowired 선언을 생략할 수 있으며, 그 결과는 다음과 같습니다.
1@SpringJUnitConfig(TestConfig.class) 2class OrderServiceIntegrationTests { 3 4 private final OrderService orderService; 5 6 OrderServiceIntegrationTests(OrderService orderService) { 7 this.orderService = orderService; 8 } 9 10 // tests that use the injected OrderService 11}
1@SpringJUnitConfig(TestConfig::class) 2class OrderServiceIntegrationTests( 3 val orderService: OrderService 4) { 5 // tests that use the injected OrderService 6}
JUnit Jupiter 테스트 메서드 또는 테스트 라이프사이클 콜백 메서드의 매개변수 타입이 ApplicationContext(또는 그 하위 타입)이고 또는 @Autowired, @Qualifier, @Value로 어노테이션 또는 메타어노테이션되어 있으면, Spring은 해당 매개변수에 대해 테스트의 ApplicationContext로부터 해당 빈을 주입합니다.
다음 예제에서 Spring은 TestConfig.class에서 로드된 ApplicationContext로부터 OrderService를 deleteOrder() 테스트 메서드에 주입합니다.
1@SpringJUnitConfig(TestConfig.class) 2class OrderServiceIntegrationTests { 3 4 @Test 5 void deleteOrder(@Autowired OrderService orderService) { 6 // use orderService from the test's ApplicationContext 7 } 8}
1@SpringJUnitConfig(TestConfig::class) 2class OrderServiceIntegrationTests { 3 4 @Test 5 fun deleteOrder(@Autowired orderService: OrderService) { 6 // use orderService from the test's ApplicationContext 7 } 8}
JUnit Jupiter의 ParameterResolver 지원이 견고하기 때문에, 하나의 메서드에 Spring뿐만 아니라 JUnit Jupiter 자체나 다른 서드파티 extensions로부터 여러 의존성을 동시에 주입할 수도 있습니다.
다음 예제는 Spring과 JUnit Jupiter가 동시에 placeOrderRepeatedly() 테스트 메서드에 의존성을 주입하는 방법을 보여줍니다.
1@SpringJUnitConfig(TestConfig.class) 2class OrderServiceIntegrationTests { 3 4 @RepeatedTest(10) 5 void placeOrderRepeatedly(RepetitionInfo repetitionInfo, 6 @Autowired OrderService orderService) { 7 8 // use orderService from the test's ApplicationContext 9 // and repetitionInfo from JUnit Jupiter 10 } 11}
1@SpringJUnitConfig(TestConfig::class) 2class OrderServiceIntegrationTests { 3 4 @RepeatedTest(10) 5 fun placeOrderRepeatedly( 6 repetitionInfo: RepetitionInfo, 7 @Autowired orderService: OrderService 8 ) { 9 10 // use orderService from the test's ApplicationContext 11 // and repetitionInfo from JUnit Jupiter 12 } 13}
JUnit Jupiter의 @RepeatedTest를 사용하면 테스트 메서드가 RepetitionInfo에 접근할 수 있습니다.
@Nested 테스트 클래스 설정_Spring TestContext Framework_는 JUnit Jupiter에서 @Nested 테스트 클래스에 대한 테스트 관련 어노테이션 사용을 지원하며, enclosing 클래스들로부터 테스트 클래스 설정을 상속하는 일급(first-class) 지원을 포함하며, 이러한 설정은 기본적으로 상속됩니다. 기본 INHERIT 모드에서 OVERRIDE 모드로 변경하려면 개별 @Nested 테스트 클래스에 @NestedTestConfiguration(EnclosingConfiguration.OVERRIDE)를 어노테이션으로 선언하면 됩니다.
명시적인 @NestedTestConfiguration 선언은 어노테이션된 테스트 클래스뿐만 아니라 그 하위 클래스 및 중첩 클래스에도 적용됩니다. 따라서 top-level 테스트 클래스에 @NestedTestConfiguration을 어노테이션으로 선언하면, 이는 모든 중첩 테스트 클래스에 재귀적으로 적용됩니다.
Spring TestContext Framework와 통합되고 enclosing 클래스 계층 구조 내에서 어노테이션 상속을 지원해야 하는 컴포넌트를 개발하는 경우,
@NestedTestConfigurationsemantics를 준수하기 위해TestContextAnnotationUtils에서 제공하는 어노테이션 검색 유틸리티를 사용해야 합니다.
예를 들어, Spring Framework 5.0에서 5.2까지의 호환성을 위해 개발 팀이 기본값을 OVERRIDE로 변경할 수 있도록, 기본 모드는 JVM 시스템 프로퍼티 또는 classpath의 root에 있는 spring.properties 파일을 통해 전역적으로 변경할 수 있습니다. 자세한 내용은 "Changing the default enclosing configuration inheritance mode" note를 참조하십시오.
다음 "Hello World" 예제는 매우 단순하지만, top-level 클래스에 선언된 공통 설정이 @Nested 테스트 클래스에 의해 상속되는 방법을 보여줍니다. 이 특정 예제에서는 TestConfig 설정 클래스만 상속됩니다.
각 중첩 테스트 클래스는 자체 활성 프로파일 집합을 제공하며, 그 결과 각 중첩 테스트 클래스에 대해 별도의 ApplicationContext가 생성됩니다(자세한 내용은 Context Caching을 참조하십시오). @Nested 테스트 클래스에서 어떤 어노테이션이 상속될 수 있는지 확인하려면 supported annotations 목록을 참조하십시오.
1@SpringJUnitConfig(TestConfig.class) 2class GreetingServiceTests { 3 4 @Nested 5 @ActiveProfiles("lang_en") 6 class EnglishGreetings { 7 8 @Test 9 void hello(@Autowired GreetingService service) { 10 assertThat(service.greetWorld()).isEqualTo("Hello World"); 11 } 12 } 13 14 @Nested 15 @ActiveProfiles("lang_de") 16 class GermanGreetings { 17 18 @Test 19 void hello(@Autowired GreetingService service) { 20 assertThat(service.greetWorld()).isEqualTo("Hallo Welt"); 21 } 22 } 23}
1@SpringJUnitConfig(TestConfig::class) 2class GreetingServiceTests { 3 4 @Nested 5 @ActiveProfiles("lang_en") 6 inner class EnglishGreetings { 7 8 @Test 9 fun hello(@Autowired service: GreetingService) { 10 assertThat(service.greetWorld()).isEqualTo("Hello World") 11 } 12 } 13 14 @Nested 15 @ActiveProfiles("lang_de") 16 inner class GermanGreetings { 17 18 @Test 19 fun hello(@Autowired service: GreetingService) { 20 assertThat(service.greetWorld()).isEqualTo("Hallo Welt") 21 } 22 } 23}
JUnit 4는 공식적으로 maintenance 모드에 있으며, Spring에서의 JUnit 4 지원은 Spring Framework 7.0부터
SpringExtension및 JUnit Jupiter를 선호하는 방향으로 deprecated되었습니다.
Spring TestContext Framework는 custom runner(JUnit 4.12 이상에서 지원)를 통해 JUnit 4와 완전히 통합됩니다. 테스트 클래스에 @RunWith(SpringJUnit4ClassRunner.class) 또는 더 짧은 @RunWith(SpringRunner.class) variant를 어노테이션으로 선언하면, 개발자는 표준 JUnit 4 기반 단위 및 통합 테스트를 구현하는 동시에 애플리케이션 컨텍스트 로딩, 테스트 인스턴스에 대한 의존성 주입, 트랜잭션 테스트 메서드 실행 등의 TestContext framework의 이점을 누릴 수 있습니다.
Spring TestContext Framework를 다른 runner(JUnit 4의 Parameterized runner 등)나 서드파티 runner(MockitoJUnitRunner 등)와 함께 사용하려는 경우, 대신 Spring’s support for JUnit rules를 선택적으로 사용할 수 있습니다.
다음 코드 목록은 custom Spring Runner로 테스트 클래스를 실행하기 위한 최소 구성 요건을 보여줍니다.
1@RunWith(SpringRunner.class) 2@TestExecutionListeners({}) 3public class SimpleTest { 4 5 @Test 6 public void testMethod() { 7 // test logic... 8 } 9}
1@RunWith(SpringRunner::class) 2@TestExecutionListeners 3class SimpleTest { 4 5 @Test 6 fun testMethod() { 7 // test logic... 8 } 9}
앞의 예제에서 @TestExecutionListeners는 기본 리스너를 비활성화하기 위해 빈 목록으로 구성됩니다. 그렇지 않으면 @ContextConfiguration을 통해 ApplicationContext를 구성해야 합니다.
JUnit 4는 공식적으로 maintenance 모드에 있으며, Spring에서의 JUnit 4 지원은 Spring Framework 7.0부터
SpringExtension및 JUnit Jupiter를 선호하는 방향으로 deprecated되었습니다.
org.springframework.test.context.junit4.rules 패키지는 다음과 같은 JUnit 4 rules(JUnit 4.12 이상에서 지원)를 제공합니다.
SpringClassRuleSpringMethodRuleSpringClassRule은 Spring TestContext Framework의 클래스 수준 기능을 지원하는 JUnit TestRule이고, SpringMethodRule은 Spring TestContext Framework의 인스턴스 수준 및 메서드 수준 기능을 지원하는 JUnit MethodRule입니다.
SpringRunner와 달리, Spring의 rule 기반 JUnit 지원은 어떤 org.junit.runner.Runner 구현에도 독립적이라는 장점이 있으므로, 기존의 alternative runner(JUnit 4의 Parameterized 등)나 서드파티 runner(MockitoJUnitRunner 등)와 결합할 수 있습니다.
TestContext framework의 전체 기능을 지원하려면 SpringClassRule과 SpringMethodRule을 결합해야 합니다. 다음 예제는 통합 테스트에서 이러한 rules를 선언하는 올바른 방법을 보여줍니다.
1// Optionally specify a non-Spring Runner via @RunWith(...) 2@ContextConfiguration 3public class IntegrationTest { 4 5 @ClassRule 6 public static final SpringClassRule springClassRule = new SpringClassRule(); 7 8 @Rule 9 public final SpringMethodRule springMethodRule = new SpringMethodRule(); 10 11 @Test 12 public void testMethod() { 13 // test logic... 14 } 15}
1// Optionally specify a non-Spring Runner via @RunWith(...) 2@ContextConfiguration 3class IntegrationTest { 4 5 @Rule 6 val springMethodRule = SpringMethodRule() 7 8 @Test 9 fun testMethod() { 10 // test logic... 11 } 12 13 companion object { 14 @ClassRule 15 val springClassRule = SpringClassRule() 16 } 17}
JUnit 4는 공식적으로 maintenance 모드에 있으며, Spring에서의 JUnit 4 지원은 Spring Framework 7.0부터
SpringExtension및 JUnit Jupiter를 선호하는 방향으로 deprecated되었습니다.
org.springframework.test.context.junit4 패키지는 JUnit 4 기반 테스트 케이스(JUnit 4.12 이상에서 지원)를 위한 다음과 같은 support 클래스들을 제공합니다.
AbstractJUnit4SpringContextTestsAbstractTransactionalJUnit4SpringContextTestsAbstractJUnit4SpringContextTests는 JUnit 4 환경에서 Spring TestContext Framework를 명시적인 ApplicationContext 테스트 지원과 통합하는 추상 기본 테스트 클래스입니다. AbstractJUnit4SpringContextTests를 상속하면, 명시적인 빈 조회를 수행하거나 컨텍스트 전체의 상태를 테스트하는 데 사용할 수 있는 protected applicationContext 인스턴스 변수에 접근할 수 있습니다.
AbstractTransactionalJUnit4SpringContextTests는 JDBC 접근을 위한 일부 편의 기능을 추가하는 AbstractJUnit4SpringContextTests의 추상 트랜잭션 확장입니다. 이 클래스는 ApplicationContext에 javax.sql.DataSource 빈과 PlatformTransactionManager 빈이 정의되어 있을 것으로 기대합니다.
AbstractTransactionalJUnit4SpringContextTests를 상속하면, 데이터베이스를 쿼리하기 위한 SQL statements를 실행하는 데 사용할 수 있는 protected jdbcTemplate 인스턴스 변수에 접근할 수 있습니다. 이러한 쿼리를 사용하여 데이터베이스 관련 애플리케이션 코드를 실행하기 전후의 데이터베이스 상태를 확인할 수 있으며, Spring은 이러한 쿼리가 애플리케이션 코드와 동일한 트랜잭션 범위 내에서 실행되도록 보장합니다.
ORM tool과 함께 사용할 때는 false positives를 피해야 합니다. JDBC Testing Support에서 언급했듯이, AbstractTransactionalJUnit4SpringContextTests는 앞서 언급한 jdbcTemplate을 사용하여 JdbcTestUtils의 메서드에 위임하는 편의 메서드도 제공합니다. 또한, AbstractTransactionalJUnit4SpringContextTests는 구성된 DataSource에 대해 SQL scripts를 실행하기 위한 executeSqlScript(..) 메서드를 제공합니다.
이러한 클래스들은 확장을 위한 편의 기능입니다. 테스트 클래스가 Spring-specific 클래스 계층 구조에 묶이는 것을 원하지 않는 경우,
@RunWith(SpringRunner.class)또는 Spring’s JUnit rules를 사용하여 custom 테스트 클래스를 구성할 수 있습니다.
org.springframework.test.context.testng 패키지는 TestNG 기반 테스트 케이스를 위한 다음과 같은 support 클래스들을 제공합니다.
AbstractTestNGSpringContextTestsAbstractTransactionalTestNGSpringContextTestsAbstractTestNGSpringContextTests는 TestNG 환경에서 Spring TestContext Framework를 명시적인 ApplicationContext 테스트 지원과 통합하는 추상 기본 테스트 클래스입니다. AbstractTestNGSpringContextTests를 상속하면, 명시적인 빈 조회를 수행하거나 컨텍스트 전체의 상태를 테스트하는 데 사용할 수 있는 protected applicationContext 인스턴스 변수에 접근할 수 있습니다.
AbstractTransactionalTestNGSpringContextTests는 JDBC 접근을 위한 일부 편의 기능을 추가하는 AbstractTestNGSpringContextTests의 추상 트랜잭션 확장입니다. 이 클래스는 ApplicationContext에 javax.sql.DataSource 빈과 PlatformTransactionManager 빈이 정의되어 있을 것으로 기대합니다.
AbstractTransactionalTestNGSpringContextTests를 상속하면, 데이터베이스를 쿼리하기 위한 SQL statements를 실행하는 데 사용할 수 있는 protected jdbcTemplate 인스턴스 변수에 접근할 수 있습니다. 이러한 쿼리를 사용하여 데이터베이스 관련 애플리케이션 코드를 실행하기 전후의 데이터베이스 상태를 확인할 수 있으며, Spring은 이러한 쿼리가 애플리케이션 코드와 동일한 트랜잭션 범위 내에서 실행되도록 보장합니다.
ORM tool과 함께 사용할 때는 false positives를 피해야 합니다. JDBC Testing Support에서 언급했듯이, AbstractTransactionalTestNGSpringContextTests는 앞서 언급한 jdbcTemplate을 사용하여 JdbcTestUtils의 메서드에 위임하는 편의 메서드도 제공합니다. 또한, AbstractTransactionalTestNGSpringContextTests는 구성된 DataSource에 대해 SQL scripts를 실행하기 위한 executeSqlScript(..) 메서드를 제공합니다.
이러한 클래스들은 확장을 위한 편의 기능입니다. 테스트 클래스가 Spring-specific 클래스 계층 구조에 묶이는 것을 원하지 않는 경우,
@ContextConfiguration,@TestExecutionListeners등을 사용하고TestContextManager로 테스트 클래스를 수동으로 instrument하여 custom 테스트 클래스를 구성할 수 있습니다. 테스트 클래스를 instrument하는 방법에 대한 예는AbstractTestNGSpringContextTests의 source code를 참조하십시오.
Parallel Test Execution
Ahead of Time Support for Tests