java 一起使用@Spy 和@Autowired

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44455572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 08:10:39  来源:igfitidea点击:

Using @Spy and @Autowired together

javaspringtestingautowiredspy

提问by Shashi K Kalia

I have a Service Class with 3 methods, Service class is also using some @Autowired annotations. Out of 3 methods, I want to mock two methods but use real method for 3rd one.

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

Problem is:

问题是:

  1. If I am using @Autowired with @Spy, all three real method implementation is being called.
  2. If I am using @Spy only, call to real method is return with Null pointer as there is no initialisation of Autowired objects.
  1. 如果我将@Autowired 与@Spy 一起使用,则会调用所有三个实际方法实现。
  2. 如果我只使用@Spy,则调用真正的方法会返回空指针,因为没有自动装配对象的初始化。

回答by PROrock

I know about these two options:

我知道这两个选项:

  1. Use @SpyBeanannotation from spring-boot-test as the only annotation
  1. 使用spring-boot-test 中的@SpyBean注释作为唯一的注释
@Autowired
@InjectMocks
private ProductController productController;

@SpyBean
private ProductService productServiceSpy;
  1. Use Java reflection to "autowire" the spy object, e.g. ReflectionTestUtils
  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);
}

回答by yuranos

I was surprised myself but it does work for us. We have plenty places like:

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

@Spy
@Autowired
private FeatureService featureService;

I think I know why you are facing this problem. It's not about injection, it's about when(bloMock.doSomeStuff()).thenReturn(1)vs doReturn(1).when(bloMock).doSomeStuff(). See: http://www.stevenschwenke.de/spyingWithMockito

我想我知道你为什么面临这个问题。这不是关于注入,而是关于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.

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

回答by Jakub Zawadzki

Using @Spytogether with @Autowiredworks until you want to verify interaction between that spy and a different component that spy is injected into. What I found to work for me was the following approach found at https://dzone.com/articles/how-to-mock-spring-bean-version-2

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

This turns your autowired component into a spy object, which will be used by your service and can be verified in your tests.

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