简体   繁体   English

Mockito无法创建@Autowired Spring-Data Repository的间谍

[英]Mockito cannot create Spy of @Autowired Spring-Data Repository

I am trying to overlay my whole test environment with Mockito.spy functionality so whenever I want i can stub a method but all other calls go to default functionality. 我试图用Mockito.spy功能覆盖我的整个测试环境,以便每当我需要时都可以对方法进行存根,但所有其他调用都转为默认功能。 This worked very well with the Service layer but I have problems with the Repository layer. 这在Service层上很好用,但是Repository层有问题。

My setup is as follows: 我的设置如下:

Mockito - 2.15.0 Spring - 5.0.8 SpringBoot - 2.0.4 Mockito-2.15.0春季-5.0.8 SpringBoot-2.0.4

Repository: 仓库:

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

Service: 服务:

@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();
    }
}

The configuration for the spy: 间谍的配置:

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

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

And my test 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());

    }
}

Now there are three possible outcomes to this test: 现在,此测试可能有三个结果:

  • aRepository is neither a mock nor a spy: aRepository既不是模拟也不是间谍:
    org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock! Example of corr...
  • aRepository is a mock but not a spy (this is the result I get): aRepository是一个模拟但不是间谍(这是我得到的结果):
    result (1):ADBO(id=null, testValue=null) result all:[]

  • aRepository is a spy (this is what I want): aRepository是一个间谍(这就是我想要的):
    result (1):ADBO(id=null, testValue=null) result all:[ADBO(id=1, testValue=bar)]

I attribute this behavior to the fact that the spring instantiation of the repository is more complex in the background and the repository is not correctly instantiated when calling Mockito.spy(ARepository.class) . 我将此行为归因于以下事实:存储库的春季实例化在后台更加复杂,并且在调用Mockito.spy(ARepository.class)时,存储库未正确实例化。

I have also tried autowireing the proper instance into the Configuration and calling Mockito.spy() with the @Autowired object. 我还尝试将正确的实例自动Mockito.spy()到Configuration中,并使用@Autowired对象调用Mockito.spy()

This results in: 结果是:

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

According to my research Mockito can mock and spy final classes since v2.0.0. 根据我的研究,从v2.0.0开始,Mockito可以模拟和监视最终类。

Calling Mockito.mockingDetails(aRepository).isSpy() returns true which leads me to think the object in the background was not correctly instantiated. 调用Mockito.mockingDetails(aRepository).isSpy()返回true ,这使我认为后台的对象未正确实例化。

Finally my question: 最后我的问题是:

How do I get a spy instance of a Spring-Data Repository in my UnitTest with @Autowired? 如何使用@Autowired在我的UnitTest中获得Spring-Data Repository的间谍实例?

You should use @SpyBean but it's unfortunately broken and doesn't work for spring data Repository 您应该使用@SpyBean但不幸的是它已损坏,不适用于Spring Data Repository

Link to the issue: http://github.com/spring-projects/spring-boot/issues/7033 链接到该问题: http : //github.com/spring-projects/spring-boot/issues/7033

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM