응용 프로그램을 시작하기 전에 @MockBean 구성 요소 구성
Spring Boot 1.4.2 어플리케이션이 있습니다.기동시에 사용되는 코드는, 다음과 같습니다.
@Component
class SystemTypeDetector{
public enum SystemType{ TYPE_A, TYPE_B, TYPE_C }
public SystemType getSystemType(){ return ... }
}
@Component
public class SomeOtherComponent{
@Autowired
private SystemTypeDetector systemTypeDetector;
@PostConstruct
public void startup(){
switch(systemTypeDetector.getSystemType()){ // <-- NPE here in test
case TYPE_A: ...
case TYPE_B: ...
case TYPE_C: ...
}
}
}
시스템 유형을 결정하는 컴포넌트가 있습니다.이 구성 요소는 다른 구성 요소에서 시작할 때 사용됩니다.생산에서는 모든 것이 잘 작동합니다.
1.Spring 1.4를 하겠습니다.@MockBean
.
테스트는 다음과 같습니다.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyWebApplication.class, webEnvironment = RANDOM_PORT)
public class IntegrationTestNrOne {
@MockBean
private SystemTypeDetector systemTypeDetectorMock;
@Before
public void initMock(){
Mockito.when(systemTypeDetectorMock.getSystemType()).thenReturn(TYPE_C);
}
@Test
public void testNrOne(){
// ...
}
}
기본적으로 조롱은 잘 통한다. ''이 되며 TypeDetectorMock을 하면 'TypeDetectorMock'이 사용됩니다.getSystemType
->TYPE_C
이 반환됩니다.
문제는 애플리케이션이 부팅되지 않는다는 것입니다.현재 스프링 작동 순서는 다음과 같습니다.
- create all Mocks (설정하지 않으면 모든 메서드가 null을 반환함)
- 응용 프로그램을 시작하다
- call @Before-methods(모크가 설정되는 장소)
- 테스트 개시
문제는 어플리케이션이 초기화되지 않은 모의로 시작된다는 것입니다.그래서 ''에 콜'은getSystemType()
manager가 됩니다.
질문입니다.애플리케이션 기동 전에 어떻게 모크를 설정할 수 있습니까?
편집: 같은 문제를 안고 있는 사람이 있는 경우, 1개의 회피책은@MockBean(answer = CALLS_REAL_METHODS)
이렇게 하면 실제 컴포넌트가 호출되어 시스템이 부팅됩니다.부팅 후 모의 동작을 변경할 수 있습니다.
을 mock보다 먼저 .@MockBean
도입되었습니다.@Primary
콘텍스트에서 원래 콩을 대체할 콩입니다.
@SpringBootTest
class DemoApplicationTests {
@TestConfiguration
public static class TestConfig {
@Bean
@Primary
public SystemTypeDetector mockSystemTypeDetector() {
SystemTypeDetector std = mock(SystemTypeDetector.class);
when(std.getSystemType()).thenReturn(TYPE_C);
return std;
}
}
@Autowired
private SystemTypeDetector systemTypeDetector;
@Test
void contextLoads() {
assertThat(systemTypeDetector.getSystemType()).isEqualTo(TYPE_C);
}
}
★★@TestConfiguration
이며 이테스트에서만 됩니다. 수 동작의 @Before
콩을 초기화하는 방법으로 이동해야 합니다.
이렇게 고칠 수 있었어요.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyWebApplication.class, webEnvironment = RANDOM_PORT)
public class IntegrationTestNrOne {
// this inner class must be static!
@TestConfiguration
public static class EarlyConfiguration {
@MockBean
private SystemTypeDetector systemTypeDetectorMock;
@PostConstruct
public void initMock(){
Mockito.when(systemTypeDetectorMock.getSystemType()).thenReturn(TYPE_C);
}
}
// here we can inject the bean created by EarlyConfiguration
@Autowired
private SystemTypeDetector systemTypeDetectorMock;
@Autowired
private SomeOtherComponent someOtherComponent;
@Test
public void testNrOne(){
someOtherComponent.doStuff();
}
}
다음의 트릭을 사용할 수 있습니다.
@Configuration
public class Config {
@Bean
public BeanA beanA() {
return new BeanA();
}
@Bean
public BeanB beanB() {
return new BeanB(beanA());
}
}
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {TestConfig.class, Config.class})
public class ConfigTest {
@Configuration
static class TestConfig {
@MockBean
BeanA beanA;
@PostConstruct
void setUp() {
when(beanA.someMethod()).thenReturn(...);
}
}
}
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★spring-boot-2.1.9.RELEASE
은 봄보다 먼저 된다.@Before
되지 않도록 .@PostConstruct
주석이 달린 메서드가 실행됩니다.
'은 '을 해보겠습니다.@Lazy
의 SystemTypeDetector
★★★★★★★★★★★★★★를 사용해 주세요.SystemTypeDetector
에 따라서, 「」에서는이 할 수 것에 .@PostConstruct
또는 동등한 후크.
의존관계를 자동화하는 방식 때문인 것 같아요.이것을 봐 주세요(특히, 「Fix #1: 설계를 해결하고 의존 관계를 표시」에 관한 부분).이 방법을 사용하면, 유저와 유저에 의한@PostConstruct
대신 컨스트럭터를 사용합니다.
사용하고 있는 것은, 유닛 테스트에 적합합니다.
org.mockito.Mockito#when()
콘텍스트가 정리되어 있을 때는, 다음의 방법으로 봄콩을 조롱해 주세요.
org.mockito.BDDMockito#given()
@SpyBean을 사용하는 경우 다른 구문을 사용해야 합니다.
willReturn(Arrays.asList(val1, val2))
.given(service).getEntities(any());
언급URL : https://stackoverflow.com/questions/40563409/configure-mockbean-component-before-application-start
'source' 카테고리의 다른 글
형식 스크립트에서 사전 선언 및 초기화 (0) | 2023.03.25 |
---|---|
모든 Spring Boot 액추에이터 엔드포인트에 프리픽스 추가 (0) | 2023.03.25 |
리퀴베이스 잠금 - 이유? (0) | 2023.03.25 |
최종 html 출력을 수정하는 WordPress 필터 (0) | 2023.03.25 |
WordPress 사이트 URL에서 index.php를 제거하는 방법 (0) | 2023.03.25 |