一起使用@Spy和@Autowired

时间:2017-06-09 10:34:53

标签: java spring testing autowired spy

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

问题是:

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

3 个答案:

答案 0 :(得分:8)

我知道这两个选项:

  1. 使用spring-boot-test中的@SpyBean注释作为唯一注释
  2. @Autowired
    @InjectMocks
    private ProductController productController;
    
    @SpyBean
    private ProductService productServiceSpy;
    
    1. 使用Java反射来“自动装配”间谍对象,例如: ReflectionTestUtils
    2. @Autowired
      private ProductController productController;
      
      @Autowired
      private ProductService productService;
      
      @Before
      public void setUp() {
          ProductService productServiceSpy = Mockito.spy(productService);
          ReflectionTestUtils.setField(productController, "productService", productServiceSpy);
      }
      

答案 1 :(得分:2)

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

@Spy
@Autowired
private FeatureService featureService;

我想我知道您为什么要面对这个问题。这与注入无关,而与when(bloMock.doSomeStuff()).thenReturn(1)doReturn(1).when(bloMock).doSomeStuff()有关。 参见:http://www.stevenschwenke.de/spyingWithMockito

  

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

答案 2 :(得分:0)

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

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