programing

Mockito는 @AutoWired Spring-Data Repository의 Spy를 생성할 수 없습니다.

abcjava 2023. 6. 25. 18:13
반응형

Mockito는 @AutoWired Spring-Data Repository의 Spy를 생성할 수 없습니다.

저는 제 모든 시험 환경을 Mockito로 덮어씌우려고 노력하고 있습니다.스파이 기능을 사용하여 내가 원할 때마다 메서드를 스텁할 수 있지만 다른 모든 호출은 기본 기능으로 이동합니다.이는 서비스 계층에서 매우 잘 작동했지만 리포지토리 계층에 문제가 있습니다.

설정은 다음과 같습니다.

Mockito - 2.15.0 스프링 - 5.0.8 스프링 부트 - 2.0.4

리포지토리:

public interface ARepository extends CrudRepository<ADBO, Long> {}

서비스:

@Service
public class AService {

    @Autowired
    ARepository aRepository;

    public ADBO getById(long id) {
        return aRepository.findById(id).orElse(null);
    }

    public Iterable<ADBO> getAll() {
        return aRepository.findAll();
    }
}

스파이에 대한 구성:

@Profile("enableSpy")
@Configuration
public class SpyConfig {

    @Bean
    @Primary
    public ARepository aRepository() {
        return Mockito.spy(ARepository.class);
    }
}

그리고 나의 시험 수업:

@ActiveProfiles("enableSpy")
@RunWith(SpringRunner.class)
@SpringBootTest
public class AServiceTest {

    @Autowired
    AService aService;

    @Autowired
    ARepository aRepository;

    @Test
    public void test() {
        ADBO foo = new ADBO();
        foo.setTestValue("bar");
        aRepository.save(foo);

        doReturn(Optional.of(new ADBO())).when(aRepository).findById(1L);
        System.out.println("result (1):" + aService.getById(1));

        System.out.println("result all:" + aService.getAll());

    }
}

이제 이 테스트의 세 가지 결과가 가능합니다.

  • 리포지토리는 가짜도 스파이도 아닙니다.
    org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock! Example of corr...
  • 리포지토리는 가짜이지만 스파이는 아닙니다(이것이 제가 얻은 결과입니다).
    result (1):ADBO(id=null, testValue=null) result all:[]

  • 리포지토리는 스파이입니다(이것이 제가 원하는 것입니다).
    result (1):ADBO(id=null, testValue=null) result all:[ADBO(id=1, testValue=bar)]

이러한 동작은 리포지토리의 봄 인스턴스화가 백그라운드에서 더 복잡하고 호출 시 리포지토리가 올바르게 인스턴스화되지 않았기 때문입니다.Mockito.spy(ARepository.class).

또한 적절한 인스턴스를 구성에 자동 배선하고 호출했습니다.Mockito.spy()@Autowired 개체를 사용합니다.

그 결과:

Cannot mock/spy class com.sun.proxy.$Proxy75
Mockito cannot mock/spy because :
 - final class

제가 조사한 바에 따르면 Mockito는 v2.0.0 이후의 최종 수업을 모의하고 감시할 수 있습니다.

부르기Mockito.mockingDetails(aRepository).isSpy()돌아온다true배경에 있는 물체가 정확하게 인스턴스화되지 않았다고 생각하게 합니다.

마지막으로 제 질문은:

@Autowired를 사용하여 UnitTest에서 Spring-Data Repository의 스파이 인스턴스를 가져오려면 어떻게 해야 합니까?

에서 사용해야 합니다.spring-boot-test.

이전에는 (Spring Boot 이슈 #7033에 따라) 고장이 났으나, 현재는 Spring Boot 이후로 수정 및 지원되고 있습니다.2.5.3.

여전히 이 오류가 발생하고 Spring Boot 버전을 업데이트할 수 없는 경우, @Mateusz Zając가 이 질문에 대해 제안한 해결 방법을 시도해 보는 것이 좋습니다.

@SpringBean이제 SpringBoot 버전 2.5.3부터 Spring 데이터 저장소와 함께 작동합니다.

업그레이드할 수 없는 경우 테스트 방법 본문에서 스파이를 인스턴스화하여 이 문제를 해결할 수 있습니다.

var yourSpy = Mockito.mock(FooRepository.class, AdditionalAnswers.delegatesTo(real))

언급URL : https://stackoverflow.com/questions/51763756/mockito-cannot-create-spy-of-autowired-spring-data-repository

반응형