통합 테스트에서 콩 덮어쓰기
Spring-Boot "RestTemplate" @Configuration " @Configuration " ( " RestTemplate " ) 。통합 테스트에서는 외부 서비스에 접속하고 싶지 않기 때문에 RestTemplate를 조롱하고 싶습니다.어떤 응답을 기대하는지 알고 있습니다.저는 통합 테스트 패키지가 실제 구현보다 우선되기를 바라며 통합 테스트 패키지에 다른 구현을 제공하려고 했지만 로그를 확인하는 것은 반대입니다: 실제 구현이 테스트 패키지보다 우선합니다.
Test Config test test 、 test test test test test test test test test test test test test test test test test test test test test?
이것은 설정 파일입니다.
@Configuration
public class RestTemplateProvider {
private static final int DEFAULT_SERVICE_TIMEOUT = 5_000;
@Bean
public RestTemplate restTemplate(){
return new RestTemplate(buildClientConfigurationFactory());
}
private ClientHttpRequestFactory buildClientConfigurationFactory() {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(DEFAULT_SERVICE_TIMEOUT);
factory.setConnectTimeout(DEFAULT_SERVICE_TIMEOUT);
return factory;
}
}
통합 테스트:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@WebAppConfiguration
@ActiveProfiles("it")
public abstract class IntegrationTest {}
Test Configuration 클래스:
@Configuration
@Import({Application.class, MockRestTemplateConfiguration.class})
public class TestConfiguration {}
마지막으로 MockRestTemplate 구성
@Configuration
public class MockRestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
return Mockito.mock(RestTemplate.class)
}
}
.4 Spring Boot 1.4.x 를 사용하는 .@MockBean
★★★★★★★★★★★★★★★★★★★★★★★★★★★
코멘트에 대한 반응:
하려면 , 「」를 사용하지 .@DirtiesContext
단, , 「」를 사용합니다.@ContextConfiguration(name = "contextWithFakeBean")
디폴트 콘텍스트는 캐시에 보관 유지하면서 별도의 콘텍스트가 생성됩니다.스프링은 두 가지(또는 컨텍스트 수)를 모두 캐시에 저장합니다.
대부분의 테스트에서는 디폴트의 폴리싱되지 않은 구성을 사용하고 있습니다만, 4~5개의 테스트에서는 가짜 콩을 사용하고 있습니다.기본 컨텍스트를 적절하게 재사용할 수 있습니다.
. 1.합니다.@Primary
★★★★
@Configuration
public class MockRestTemplateConfiguration {
@Bean
@Primary
public RestTemplate restTemplate() {
return Mockito.mock(RestTemplate.class)
}
}
2. 단, Spring Rest Template 테스트 지원에 대해 살펴보는 것이 좋습니다.다음은 간단한 예입니다.
private MockRestServiceServer mockServer;
@Autowired
private RestTemplate restTemplate;
@Autowired
private UsersClient usersClient;
@BeforeMethod
public void init() {
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void testSingleGet() throws Exception {
// GIVEN
int testingIdentifier = 0;
mockServer.expect(requestTo(USERS_URL + "/" + testingIdentifier))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(TEST_RECORD0, MediaType.APPLICATION_JSON));
// WHEN
User user = usersClient.getUser(testingIdentifier);
// THEN
mockServer.verify();
assertEquals(user.getName(), USER0_NAME);
assertEquals(user.getEmail(), USER0_EMAIL);
}
자세한 예는 이쪽의 Github repo에서 확인할 수 있습니다.
에 문제가 은, 「」, 「이러다」를 사용하고 있는 입니다.@Configuration
를 참조하십시오.이것으로 메인 설정이 바뀝니다.대신 를 사용하여 기본 구성을 추가(덮어쓰기)합니다.
프라이머리 설정을 커스터마이즈 하는 경우는, 네스트된 @TestConfiguration 클래스를 사용할 수 있습니다.응용 프로그램의 프라이머리 구성 대신 사용되는 네스트된 @Configuration 클래스와 달리 네스트된 @TestConfiguration 클래스는 응용 프로그램의 프라이머리 구성과 함께 사용됩니다.
Spring Boot 사용 예:
메인 클래스
@SpringBootApplication() // Will scan for @Components and @Configs in package tree
public class Main{
}
메인 구성
@Configuration
public void AppConfig() {
// Define any beans
}
테스트 설정
@TestConfiguration
public void AppTestConfig(){
// override beans for testing
}
테스트 클래스
@RunWith(SpringRunner.class)
@Import(AppTestConfig.class)
@SpringBootTest
public void AppTest() {
// use @MockBean if you like
}
주의: 덮어쓰는 콩도 모두 작성됩니다.@Profile
에 나타내지 @Configuration
.
@MockBean
콩 오버라이딩
하려고 합니다.@MockBean
실제 실장을 잊기 위해서: 일반적으로 슬라이스 테스트나 인테그레이션 테스트에서는 테스트하고 있는 클래스가 있는 콩을 로드하지 않고 이들 콩을 통합 테스트하고 싶지 않은 경우에 사용합니다.
으로 그들을 .null
테스트를 완료하기 위한 최소한의 행동을 조롱할 것입니다.
@WebMvcTest
레이어를 않기 에 그 한 경우가 .@SpringBootTest
또, 테스트 설정으로 bean 설정의 서브셋만을 지정하는 경우에도, 다음과 같이 요구될 수 있습니다.
가능한 한 에, 「실제 컴포넌트」는 않는 것이 .@MockBean
덮어쓰는 이 콩을 덮어쓰게 됩니다. 콩을 덮어쓰게 됩니다.
@SpringBootTest({"spring.main.allow-bean-definition-overriding=true"})
@Import(FooTest.OverrideBean.class)
public class FooTest{
@Test
public void getFoo() throws Exception {
// ...
}
@TestConfiguration
public static class OverrideBean {
// change the bean scope to SINGLETON
@Bean
@Scope(ConfigurableBeanFactory.SINGLETON)
public Bar bar() {
return new Bar();
}
// use a stub for a bean
@Bean
public FooBar BarFoo() {
return new BarFooStub();
}
// use a stub for the dependency of a bean
@Bean
public FooBar fooBar() {
return new FooBar(new StubDependency());
}
}
}
좀 더 깊이 파고들면, 제 두 번째 답을 보세요.
다음 방법으로 문제를 해결했습니다.
@SpringBootTest(classes = {AppConfiguration.class, AppTestConfiguration.class})
대신
@Import({ AppConfiguration.class, AppTestConfiguration.class });
내 경우 테스트는 앱과 동일한 패키지에 포함되어 있지 않습니다.따라서 AppConfiguration.class(또는 App.class)를 명시적으로 지정해야 합니다.만약 당신이 테스트에서 같은 패키지를 사용한다면, 당신은 그냥 쓸 수 있을 것이다.
@SpringBootTest(classes = AppTestConfiguration.class)
(동작하지 않는) 대신
@Import(AppTestConfiguration.class );
이것이 매우 다른 것을 보는 것은 꽤 잘 알려져 있다.마마 、 누걸걸걸걸걸 거을을 。을 사용하다하실 수도 있어요.@Import(...)
는 선택되지 않습니다.@SpringBootTests
는 존재하지만 로그에는 우선되는 빈이 표시됩니다.하지만 그 반대야.
런데, using using using를 @TestConfiguration
, ★★★★★★★★★★★★★★★★」@Configuration
역시 차이가 없습니다.
@Primary 주석에서는 Bean override는 Spring Boot 1.5.X에서는 동작하지만 Spring Boot 2.1.X에서는 실패합니다.throw 오류:
Invalid bean definition with name 'testBean' defined in sample..ConfigTest$SpringConfig:..
There is already .. defined in class path resource [TestConfig.class]] bound
.properties=
스프링에게 덮어쓰기를 허용하도록 명시적으로 지시할 것입니다. 을 사용하다
@SpringBootTest(properties = ["spring.main.allow-bean-definition-overriding=true"])
업데이트: application-test.yml에서도 동일한 속성을 추가할 수 있습니다(파일명은 테스트에 사용하는 테스트 프로파일명에 따라 다릅니다).
하나의 메서드만 덮어쓰고 싶었기 때문에 테스트에서 내부 구성 클래스를 선언했습니다.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FileNotificationWebhookTest{
public static class FileNotificationWebhookTestConfiguration {
@Bean
@Primary
public FileJobRequestConverter fileJobRequestConverter() {
return new FileJobRequestConverter() {
@Override
protected File resolveWindowsPath(String path) {
return new File(path);
}
};
}
}
}
하지만,
@SpringBoot에서의 설정 선언테스트가 작동하지 않았습니다.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,classes = {FileNotificationWebhookTest.FileNotificationWebhookTestConfiguration.class})
또는 @Configuration을 사용하여 테스트 설정에 주석을 달지 않았습니다.
@Configuration
public static class FileNotificationWebhookTestConfiguration {
}
그 결과,
원인: org.springframework.context.Application Context Exception:웹 서버를 시작할 수 없습니다. 중첩된 예외는 org.springframework.context입니다.Application Context Exception:ServletWebServerFactory 빈이 없으므로 ServletWebServerApplicationContext를 시작할 수 없습니다.
(여기에 게재된 다른 투고와는 달리) @Import를 사용하는 것이 효과적이었다.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Import(FileNotificationWebhookTest.FileNotificationWebhookTestConfiguration.class)
class FileNotificationWebhookTest {
}
스프링 사용: 5.3.3 (스프링 부트 스타터 포함): 2.4.2
@MockBean
는 프로덕션 빌드 대신 모키토 모크를 생성합니다.
Mockito를대체 있는 에는 Mockito를 하여 사용할 것을 합니다.@TestConfiguration
1.4및 ('1.4.0')@Primary
석입니니다다
@TestConfiguration
하고 "사용할 수 있는 컨텍스트"를 합니다.@TestConfiguration
조각이 더해져요." " " @Primary
RestTemplate 를를를를 。
다음의 간단한 예를 참조해 주세요.
@SpringBootTest
public class ServiceTest {
@TestConfiguration
static class AdditionalCfg {
@Primary
@Bean
RestTemplate rt() {
return new RestTemplate() {
@Override
public String exec() {
return "Test rest template";
}
};
}
}
@Autowired
MyService myService;
@Test
void contextLoads() {
assertThat(myService.invoke()).isEqualTo("Test rest template");
}
}
이거 진짜 이상하다.
내 경우(Spring Boot 2.6.7), 커스텀 @Primary @Bean을 포함한 @MyTestConfiguration을 @SpringBoot에 Import하기만 하면 됩니다.테스트, 그리고 모든 게 성공했어
내 콩의 이름을 분명히 지어야 할 때 까지 말이야그러다가 갑자기...
@SpringBootTest(
properties = ["spring.main.allow-bean-definition-overriding=true"],
classes = [MyTestConfig::class],
)
이 답변과 해당 스레드에 제공된 다른 답변을 함께 확인하십시오.Spring Boot 2.X에서 bean을 덮어쓰는 것입니다.이 경우 이 옵션은 기본적으로 비활성화되어 있습니다.또한 만약 당신이 그 방법을 선택하기로 결정했다면, 그것은 어떻게 Bean Definition DSL을 사용하는지에 대한 몇 가지 아이디어도 가지고 있다.
가장 간단한 해결책은 application.properties에서 이 속성을 설정하는 것입니다.
spring.main.allow-bean-definition-overriding=true
이렇게 하면 콩을 덮어쓸 수 있습니다.
다음으로 테스트에서 컨피규레이션클래스를 만들고 콩에 주석을 붙입니다.
@Bean
@Primary
이렇게 하면 이 콩이 테스트 시 일반적인 콩보다 우선됩니다.
언급URL : https://stackoverflow.com/questions/35742920/overriding-beans-in-integration-tests
'source' 카테고리의 다른 글
도커에서 마리애드브에 원격접속하는 방법은? (0) | 2022.09.11 |
---|---|
암호화 및 복호화, md5 (0) | 2022.09.11 |
간단한 설명 PHP OOP vs 프로시저? (0) | 2022.09.11 |
원시 길이 배열을 긴 길이 목록으로 변환 (0) | 2022.09.11 |
스프링 부트:최대 연결 수 등의 JDBC 풀 속성을 설정하려면 어떻게 해야 합니까? (0) | 2022.09.11 |