Java 将@Spy和@Autowired一起使用

Java 将@Spy和@Autowired一起使用,java,spring,testing,autowired,spy,Java,Spring,Testing,Autowired,Spy,我有一个包含3个方法的服务类,服务类也使用了一些@Autowired注释。 在三种方法中,我想模拟两种方法,但第三种方法使用实方法 问题是: 如果我使用@Autowired和@Spy,那么将调用所有三个实际方法实现 若我只使用@Spy,那个么对real方法的调用将返回空指针,因为并没有自动连接对象的初始化 我知道这两种选择: 使用spring boot test中的注释作为唯一的注释 @Autowired @注射模拟 私有产品控制器产品控制器; @间谍 私人产品服务产品服务间谍; 使用Java

我有一个包含3个方法的服务类,服务类也使用了一些@Autowired注释。 在三种方法中,我想模拟两种方法,但第三种方法使用实方法

问题是:

  • 如果我使用@Autowired和@Spy,那么将调用所有三个实际方法实现
  • 若我只使用@Spy,那个么对real方法的调用将返回空指针,因为并没有自动连接对象的初始化

  • 我知道这两种选择:

  • 使用spring boot test中的注释作为唯一的注释
  • @Autowired
    @注射模拟
    私有产品控制器产品控制器;
    @间谍
    私人产品服务产品服务间谍;
    
  • 使用Java反射“自动连接”spy对象,例如
  • @Autowired
    私有产品控制器产品控制器;
    @自动连线
    私人产品服务;
    @以前
    公共作废设置(){
    ProductService productServiceSpy=Mockito.spy(ProductService);
    ReflectionTestUtils.setField(productController,“productService”,productServiceSpy);
    }
    
    我自己也很惊讶,但它确实对我们有用。我们有很多地方,比如:

    @Spy
    @Autowired
    private FeatureService featureService;
    
    我想我知道你为什么要面对这个问题。它不是关于注入,而是关于
    when(bloMock.doSomeStuff())。然后返回(1)
    vs
    doReturn(1)。when(bloMock.doSomeStuff()
    )。 见:

    非常重要的区别是第一个选项实际上 调用doSomeStuff()-方法,而第二个方法不调用。双方都会 使doSomeStuff()返回所需的1


    @Spy
    @Autowired
    一起使用,直到您想要验证该Spy与插入该Spy的不同组件之间的交互为止。我发现对我有效的方法是在


    这将使您的自动连线组件成为间谍对象,您的服务将使用该对象,并且可以在测试中进行验证。

    他们的文档也提到了这一点。请参阅“关于监视真实对象的重要信息!”一节:我不确定这是否在某个时候起作用,但对我来说,它只在使用
    @SpyBeans
    而不是
    @Spy
    时起作用。第一个解决方案很好。我不知道
    @SpyBean
    。非常感谢。
    @InjectMocks
    'ed对象必须为每个
    @Mock
    都有显式的setter。当我运行此代码时,它会在启动过程中以循环依赖关系失败。是否需要执行其他步骤?
    @Configuration
    public class AddressServiceTestConfiguration {
        @Bean
        @Primary
        public AddressService addressServiceSpy(AddressService addressService) {
            return Mockito.spy(addressService);
        }
    }