IT이야기

Spring JUnit : autowired component에서 autowired component를 모의하는 방법

cyworld 2021. 4. 14. 20:50
반응형

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
 }
}

참조 URL : https://stackoverflow.com/questions/19299513/spring-junit-how-to-mock-autowired-component-in-autowired-component

반응형