[SPRING] @ComponentScan을 Spring의 테스트 특정 컨텍스트 구성과 함께 사용하는 방법 Junit4 TestRunner?
SPRING@ComponentScan을 Spring의 테스트 특정 컨텍스트 구성과 함께 사용하는 방법 Junit4 TestRunner?
Spring Boot 애플리케이션을 테스트하고있다. 몇 가지 테스트 클래스가 있는데, 각각은 조롱 된 또는 다른 방식으로 사용자 정의 된 빈 집합이 필요합니다.
다음은 설정에 대한 스케치입니다.
src / main / java :
package com.example.myapp;
@SpringBootApplication
@ComponentScan(
basePackageClasses = {
MyApplication.class,
ImportantConfigurationFromSomeLibrary.class,
ImportantConfigurationFromAnotherLibrary.class})
@EnableFeignClients
@EnableHystrix
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
package com.example.myapp.feature1;
@Component
public class Component1 {
@Autowired
ServiceClient serviceClient;
@Autowired
SpringDataJpaRepository dbRepository;
@Autowired
ThingFromSomeLibrary importantThingIDontWantToExplicitlyConstructInTests;
// methods I want to test...
}
src / test / java :
package com.example.myapp;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class Component1TestWithFakeCommunication {
@Autowired
Component1 component1; // <-- the thing we're testing. wants the above mock implementations of beans wired into it.
@Autowired
ServiceClient mockedServiceClient;
@Configuration
static class ContextConfiguration {
@Bean
@Primary
public ServiceClient mockedServiceClient() {
return mock(ServiceClient.class);
}
}
@Before
public void setup() {
reset(mockedServiceClient);
}
@Test
public void shouldBehaveACertainWay() {
// customize mock, call component methods, assert results...
}
}
package com.example.myapp;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class Component1TestWithRealCommunication {
@Autowired
Component1 component1; // <-- the thing we're testing. wants the real implementations in this test.
@Autowired
ServiceClient mockedServiceClient;
@Before
public void setup() {
reset(mockedServiceClient);
}
@Test
public void shouldBehaveACertainWay() {
// call component methods, assert results...
}
}
위의 설정 문제는 MyApplication에서 구성한 구성 요소 검사가 Component1TestWithFakeCommunication.ContextConfiguration을 선택하기 때문에 실제 ServiceClient 구현이 필요한 Component1TestWithRealCommunication에서도 모의 ServiceClient가 발생합니다.
@Autowired 생성자를 사용할 수는 있지만 두 테스트 모두에서 구성 요소를 직접 빌드 할 수는 있지만 복잡한 설정이 필요한 충분한 양의 Spring TestContext를 설정해야합니다 (예 : Spring Data JPA 리포지토리, 라이브러리의 구성 요소 스프링 컨텍스트에서 콩을 가져 오는 응용 프로그램 외부). Spring 컨텍스트 내에서 특정 bean 정의를 로컬 적으로 오버라이드 할 수있는 테스트 내에서 Spring 컨피규레이션을 중첩하는 것은 이것을 수행하는 깔끔한 방법처럼 느껴진다. 유일한 단점은 이러한 중첩 된 구성이 결국 MyApplication (구성 요소가 앱 패키지를 검색)에서 구성을 기반으로하는 모든 Spring TestContext 테스트에 영향을 미친다는 것입니다.
각 테스트 클래스에서 로컬로 오버라이드 된 빈을 몇 개만 가지고 테스트를위한 "대부분의 실제"스프링 컨텍스트를 얻도록 설정을 수정하려면 어떻게해야합니까?
해결법
-
==============================
1.다음은 현재 테스트 클래스에만 적용 할 수있는 새로운 위조 통신 프로파일을 도입하여 목표를 달성하는 데 도움이됩니다.
다음은 현재 테스트 클래스에만 적용 할 수있는 새로운 위조 통신 프로파일을 도입하여 목표를 달성하는 데 도움이됩니다.
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MyApplication.class) @WebAppConfiguration @ActiveProfiles({"test", "fake-communication"}) public class Component1TestWithFakeCommunication { // @Autowired ... @Profile("fake-communication") @Configuration static class ContextConfiguration { @Bean @Primary public ServiceClient mockedServiceClient() { return mock(ServiceClient.class); } } }
-
==============================
2.@SpringBootTest가있는 경우 @MockBean으로 모의하려는 서비스에만 주석을 달 수 있습니다. 저것과 같이 쉬운.
@SpringBootTest가있는 경우 @MockBean으로 모의하려는 서비스에만 주석을 달 수 있습니다. 저것과 같이 쉬운.
-
==============================
3.나는 두 가지 일을 할 것이다.
나는 두 가지 일을 할 것이다.
Spring은 테스트 빈을 조롱하기에 충분한 정보를 제공해야하지만 런타임시 ApplicationContext가 테스트 빈을 알아 채지 못하게해야한다.
-
==============================
4.다른 명시 적 프로파일을 사용하여 테스트 구성을 선택하지 않도록 할 수 있습니다 (다른 대답에서 제안 된 것처럼). 나는 또한 그것을했고 심지어 도서관 지원을 만들었다.
다른 명시 적 프로파일을 사용하여 테스트 구성을 선택하지 않도록 할 수 있습니다 (다른 대답에서 제안 된 것처럼). 나는 또한 그것을했고 심지어 도서관 지원을 만들었다.
그러나 Spring-Boot는 영리하며이 문제를 자동으로 해결하는 "유형 필터"가 내장되어 있습니다. 이 작업을 수행하려면 @ComponentScan 주석을 제거해야합니다. @ComponentScan 주석은 테스트 구성을 찾아서 @SpringBootApplication이 작업을 수행하게합니다. 귀하의 예에서는 다음을 제거하십시오.
@SpringBootApplication @ComponentScan( basePackageClasses = { MyApplication.class, ImportantConfigurationFromSomeLibrary.class, ImportantConfigurationFromAnotherLibrary.class})
다음과 같이 바꿉니다.
@SpringBootApplication(scanBasePackageClasses= { MyApplication.class, ImportantConfigurationFromSomeLibrary.class, ImportantConfigurationFromAnotherLibrary.class})
또한 테스트를 @SpringBootTest로 주석 처리해야 할 수도 있습니다. 이것은 현재 테스트에있는 것을 제외하고 내부 클래스 구성 (및 구성 요소)을 자동 스캔하지 않아야합니다.
from https://stackoverflow.com/questions/39300167/how-to-use-componentscan-together-with-test-specific-contextconfigurations-in-s by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring : classpath 자원을위한 URL 삽입 (0) | 2019.04.16 |
---|---|
[SPRING] Spring REST 컨트롤러를 테스트 할 때 @AuthenticationPrincipal 삽입 (0) | 2019.04.16 |
[SPRING] 스프링 부트 obfuscator (0) | 2019.04.16 |
[SPRING] 스프링 애플리케이션 컨텍스트 이벤트를 다른 컨텍스트로 연결하는 방법 (0) | 2019.04.16 |
[SPRING] Mockito @ InjectMocks는 어떻게 작동합니까? (0) | 2019.04.15 |