一起使用@Spy 和@Autowired

Using @Spy and @Autowired together

我有一个服务 Class 有 3 个方法,服务 class 也使用了一些 @Autowired 注释。 在 3 种方法中,我想模拟两种方法,但对第 3 种方法使用真实方法。

问题是:

  1. 如果我将@Autowired 与@Spy 一起使用,则会调用所有三个实际方法实现。
  2. 如果我只使用@Spy,调用真正的方法是return使用空指针,因为没有初始化自动装配对象。

我知道这两个选项:

  1. 使用来自 spring-boot-test 的 @SpyBean 注释作为唯一的注释
@Autowired
@InjectMocks
private ProductController productController;

@SpyBean
private ProductService productServiceSpy;
  1. 使用 Java 反射 "autowire" 间谍对象,例如ReflectionTestUtils
@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) vs doReturn(1).when(bloMock).doSomeStuff()。 参见:http://www.stevenschwenke.de/spyingWithMockito

The very important difference is that the first option will actually call the doSomeStuff()- method while the second will not. Both will cause doSomeStuff() to return the desired 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);
    }
}

这会将您的自动装配组件变成一个间谍对象,您的服务将使用该对象并可在您的测试中对其进行验证。