Using @Spy and @Autowired together

前端 未结 3 1115
时光取名叫无心
时光取名叫无心 2021-02-04 04:49

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条回答
  • 2021-02-04 05:24

    Using @Spy together with @Autowired works 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

    @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.

    0 讨论(0)
  • 2021-02-04 05:34

    I know about these two options:

    1. Use @SpyBean annotation from spring-boot-test as the only annotation
    @Autowired
    @InjectMocks
    private ProductController productController;
    
    @SpyBean
    private ProductService productServiceSpy;
    
    1. Use Java reflection to "autowire" the spy object, e.g. ReflectionTestUtils
    @Autowired
    private ProductController productController;
    
    @Autowired
    private ProductService productService;
    
    @Before
    public void setUp() {
        ProductService productServiceSpy = Mockito.spy(productService);
        ReflectionTestUtils.setField(productController, "productService", productServiceSpy);
    }
    
    0 讨论(0)
  • 2021-02-04 05:49

    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

    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.

    0 讨论(0)
提交回复
热议问题