source

봄 JUnit:자동 배선 구성 요소에서 자동 배선 구성 요소를 모의하는 방법

lovecheck 2023. 3. 18. 08:43
반응형

봄 JUnit:자동 배선 구성 요소에서 자동 배선 구성 요소를 모의하는 방법

테스트할 스프링 컴포넌트가 있는데 이 컴포넌트에는 유닛테스트를 위해 변경해야 하는 자동배선 속성이 있습니다.문제는 클래스가 포스트 컨스트럭트 메서드 내에서 자동 배선된 컴포넌트를 사용하기 때문에 교체할 수 없다는 것입니다(즉, Reflection을 통해).Test Utils)를 참조하십시오.

어떻게 하면 좋을까요?

테스트하는 클래스는 다음과 같습니다.

@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구체적으로는 다음과 같이 동작합니다.

// 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에서는 테스트용 주석이 도입되었습니다.따라서 Spring Boot에서는 Spring beat에 대한 조롱과 스파이 기능이 기본적으로 지원됩니다.

새로운 testContext.xml을 지정할 수 있습니다.@Autowired정의하는 빈은 테스트에 필요한 유형입니다.

나는 그 주제에 대한 블로그 게시물을 만들었다.또한 Github 저장소에 대한 링크와 작업 예도 포함되어 있습니다.

요령은 테스트 구성을 사용하는 것입니다. 테스트 구성에서는 원래 스프링빈을 가짜로 덮어씁니다.사용할 수 있습니다.@Primary그리고.@Profile이 트릭에 대한 주석입니다.

spring-inject https://github.com/sgri/spring-reinject/ 를 사용하면 mocks로 bean 정의를 덮어쓸 수 있습니다.

통합 테스트의 또 다른 접근법은 새로운 구성 클래스를 정의하여 사용자 정의로 제공하는 것입니다.@ContextConfiguration구성에서는 원두를 모조할 수 있으며 테스트/초 흐름에서 사용하는 모든 유형의 원두를 정의해야 합니다.예를 들면 다음과 같습니다.

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

Junit5의 경우 다음을 사용하여 모의할 수 있습니다.

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class MytestClass {

@Mock
MyInjectedSevice myInjservice;

@InjectMock
MyService myservice;

}
import org.junit.Before;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import javax.annotation.Resource;

@Mock
    private IMyInterface yInterface;

    @InjectMocks
    @Resource
    ResourceDependant resourceDependant = new resourceDependant();


    @Before
    public void initMocksForInjection() throws Exception {
        MockitoAnnotations.openMocks(this);
    }

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

반응형