一起使用@Spy和@Autowired

Sha*_*lia 6 java testing spring autowired spy

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

问题是:

  1. 如果我在@Spy中使用@Autowired,则会调用所有三个真正的方法实现.
  2. 如果我只使用@Spy,则调用real方法返回Null指针,因为没有自动对象的初始化.

PRO*_*ock 14

我知道这两个选项:

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

@SpyBean
private ProductService productServiceSpy;
Run Code Online (Sandbox Code Playgroud)
  1. 使用Java反射来"自动装配"间谍对象,例如ReflectionTestUtils
@Autowired
private ProductController productController;

@Autowired
private ProductService productService;

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

  • 第一个解决方案很好。我不知道“@SpyBean”。谢谢你! (3认同)

yur*_*s87 14

我自己也很惊讶,但它确实对我们有用。我们有很多地方,例如:

@Spy
@Autowired
private FeatureService featureService;
Run Code Online (Sandbox Code Playgroud)

我想我知道你为什么面临这个问题。这不是关于注入,而是关于when(bloMock.doSomeStuff()).thenReturn(1)vs doReturn(1).when(bloMock).doSomeStuff()。见:http : //www.stevenschwenke.de/spyingWithMockito

非常重要的区别在于,第一个选项实际上会调用 doSomeStuff()- 方法,而第二个选项则不会。两者都会导致 doSomeStuff() 返回所需的 1。


小智 6

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Jos*_*eón 5

我有一个类似的问题,我们一起使用 @SpyBean 和 @Autowired 修复了:

  @SpyBean
  @Autowired
  ClosedInvoiceEventHandler closedInvoiceEventHandler;
Run Code Online (Sandbox Code Playgroud)