Spring JUnit : autowired component에서 autowired component를 모의하는 방법
테스트하고 싶은 Spring 컴포넌트가 있고이 컴포넌트에는 단위 테스트를 위해 변경해야하는 autowired 속성이 있습니다. 문제는 클래스가 post-construct 메서드 내에서 autowired 구성 요소를 사용하므로 실제로 사용되기 전에 (즉 ReflectionTestUtils를 통해) 대체 할 수 없다는 것입니다.
어떻게해야합니까?
테스트하려는 클래스입니다.
@Component
public final class TestedClass{
@Autowired
private Resource resource;
@PostConstruct
private void init(){
//I need this to return different result
resource.getSomething();
}
}
그리고 이것이 테스트 케이스의 기본입니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= "classpath:applicationContext.xml")
public class TestedClassTest{
@Autowired
private TestedClass instance;
@Before
private void setUp(){
//this doesn't work because it's executed after the bean is instantiated
ReflectionTestUtils.setField(instance, "resource", new Resource("something"));
}
}
postconstruct 메서드가 호출되기 전에 리소스를 다른 것으로 대체하는 방법이 있습니까? Spring JUnit 러너에게 다른 인스턴스를 자동 연결하도록 지시하고 싶습니까?
@Autowired
정의한 Bean이 테스트에 필요한 유형 인 새 testContext.xml을 제공 할 수 있습니다 .
Mockito를 사용할 수 있습니다 . PostConstruct
구체적으로 잘 모르겠지만 일반적으로 작동합니다.
// Create a mock of Resource to change its behaviour for testing
@Mock
private Resource resource;
// Testing instance, mocked `resource` should be injected here
@InjectMocks
@Resource
private TestedClass testedClass;
@Before
public void setUp() throws Exception {
// Initialize mocks created above
MockitoAnnotations.initMocks(this);
// Change behaviour of `resource`
when(resource.getSomething()).thenReturn("Foo");
}
Spring Boot 1.4는 @MockBean
. 이제 Spring Bean에 대한 조롱 및 감시는 기본적으로 Spring Boot에서 지원됩니다.
주제에 대한 블로그 게시물을 작성했습니다 . 작업 예제와 함께 Github 저장소에 대한 링크도 포함되어 있습니다.
트릭은 테스트 구성을 사용하여 원래 스프링 빈을 가짜로 재정의합니다. 이 트릭에 @Primary
및 @Profile
주석을 사용할 수 있습니다 .
spring-reinject https://github.com/sgri/spring-reinject/를 사용 하여 모의로 빈 정의를 재정의 할 수 있습니다.
통합 테스트의 또 다른 접근 방식은 새 구성 클래스를 정의하고 @ContextConfiguration
. 설정에서 당신은 당신의 bean을 모의 할 수있을 것이고 또한 당신은 test / s flow에서 사용하고있는 모든 유형의 bean을 정의해야합니다. 예를 제공하려면 :
@RunWith(SpringRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class MockTest{
@Configuration
static class ContextConfiguration{
// ... you beans here used in test flow
@Bean
public MockMvc mockMvc() {
return MockMvcBuilders.standaloneSetup(/*you can declare your controller beans defines on top*/)
.addFilters(/*optionally filters*/).build();
}
//Defined a mocked bean
@Bean
public MyService myMockedService() {
return Mockito.mock(MyService.class);
}
}
@Autowired
private MockMvc mockMvc;
@Autowired
MyService myMockedService;
@Before
public void setup(){
//mock your methods from MyService bean
when(myMockedService.myMethod(/*params*/)).thenReturn(/*my answer*/);
}
@Test
public void test(){
//test your controller which trigger the method from MyService
MvcResult result = mockMvc.perform(get(CONTROLLER_URL)).andReturn();
// do your asserts to verify
}
}
'IT이야기' 카테고리의 다른 글
Passport.js 인증 실패시 JSON 응답을 다시 보내기 (0) | 2021.04.15 |
---|---|
Spring @Value가 속성 파일의 값으로 확인되지 않을 경우 (0) | 2021.04.15 |
나머지 세로 공간 채우기-CSS (0) | 2021.04.14 |
사설 git 서버 (SSH)를 사용하여 bower 패키지를 설치하는 방법 (0) | 2021.04.14 |
Ansible로 디렉토리를 복사하는 것이 왜 그렇게 느린것일까..? (0) | 2021.04.14 |