programing

@Spy 및 @Autowired 함께 사용

easyjava 2023. 9. 6. 23:05
반응형

@Spy 및 @Autowired 함께 사용

저는 3가지 방법으로 서비스 클래스를 운영하고 있으며, 서비스 클래스는 또한 일부 @Autowired 주석을 사용하고 있습니다.3가지 방법 중에서 2가지 방법을 모의해보고 싶은데 3번째 방법은 진짜 방법을 사용합니다.

문제는 다음과 같습니다.

  1. @Autowired with @Spy를 사용하는 경우 세 가지 실제 메서드 구현이 모두 호출됩니다.
  2. @Spy만 사용하는 경우 자동 연결 개체의 초기화가 없으므로 실제 메서드로 호출하는 것이 Null 포인터로 반환됩니다.

저는 이 두 가지 옵션에 대해 알고 있습니다.

  1. spring-boot-test의 @SpyBean 주석을 유일한 주석으로 사용
@Autowired
@InjectMocks
private ProductController productController;

@SpyBean
private ProductService productServiceSpy;
  1. Java reflection을 사용하여 스파이 객체(예: Reflection)를 "자동 배선"합니다.테스트 유틸리티
@Autowired
private ProductController productController;

@Autowired
private ProductService productService;

@Before
public void setUp() {
    ProductService productServiceSpy = Mockito.spy(productService);
    ReflectionTestUtils.setField(productController, "productService", productServiceSpy);
}

저도 깜짝 놀랐지만 저희한테는 효과가 있어요.다음과 같은 장소가 많이 있습니다.

@Spy
@Autowired
private FeatureService featureService;

나는 당신이 왜 이 문제에 직면하고 있는지 알 것 같습니다.주사에 관한 것이 아니라, 그에 관한 것입니다.when(bloMock.doSomeStuff()).thenReturn(1)doReturn(1).when(bloMock).doSomeStuff(). 참조: http://www.stevenschwenke.de/spyingWithMockito

가장 중요한 차이점은 첫 번째 옵션이 실제로 doSomeStuff()- 메서드를 호출하는 반면 두 번째 옵션은 호출하지 않는다는 것입니다.둘 다 doSomeStuff()가 원하는 1을 반환하게 됩니다.

을 해서.@Spy 함께@Autowired스파이와 스파이가 주입되는 다른 구성 요소 간의 상호 작용을 확인할 때까지 작동합니다.저는 https://dzone.com/articles/how-to-mock-spring-bean-version-2 에서 발견한 다음과 같은 접근 방식이 제게 적합하다는 것을 알게 되었습니다.

@Configuration
public class AddressServiceTestConfiguration {
    @Bean
    @Primary
    public AddressService addressServiceSpy(AddressService addressService) {
        return Mockito.spy(addressService);
    }
}

이렇게 하면 자동 배선된 구성 요소가 스파이 개체로 전환되어 서비스에서 사용되며 테스트에서 확인할 수 있습니다.

비슷한 문제가 있는데 @SpyBean과 @Autowired를 함께 사용하여 수정했습니다.

  @SpyBean
  @Autowired
  ClosedInvoiceEventHandler closedInvoiceEventHandler;

UPDATE 20220509-203459

TestNg 사용자의 경우 테스트 클래스에 추가

@TestExecutionListener(리스너 = MockitoTestExecutionListener.class)

Abstract Transactional TestNGspringContextTests를 확장합니다.

그러면 @스파이빈이 작동할 것입니다.


이 답변에는 두 가지 선택 사항이 있습니다.

그런데 문제가 생겼습니다.

  1. spring-boot-test의 @SpyBean 주석을 유일한 주석으로 사용

이것은 좋은 생각인 것 같지만 단지 준잇 사용자들을 위한 것입니다.저는 시험에 TestNg를 사용하고 있습니다.@SpyBean이 TestNg와 잘 작동할 수 있는 방법을 찾지 못했습니다.

  1. Java reflection을 사용하여 스파이 객체(예: Reflection)를 "자동 배선"합니다.테스트 유틸리티

봄이 이미 그것들을 대리하고 방법을 최종적으로 만들기 때문에 자동으로 재배된 콩들은 모두 최종적인 방법들을 가지고 있는 것처럼 보입니다.그래서 모키토.자동차로 만든 콩을 염탐하는 것은 불가능할지도 모릅니다.

실제로 시도해보니 예외가 있었습니다.

잘못된 인수 일치자 사용 0 일치자 예상 1이 기록되었습니다.

나는 이유를 스스로 찾지 못했지만 여기서 설명을 보았습니다.

이제 남은 방법은 https://stackoverflow.com/a/55148514/12133207 뿐입니다.

효과가 있는지 잘 모르겠습니다. 노력해 보겠습니다. method parameter도 spring 프록시로 되어 있기 때문일 수도 있습니다.방법도 최종적입니다.

언급URL : https://stackoverflow.com/questions/44455572/using-spy-and-autowired-together

반응형