Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 1163 Vote(s) - 3.52 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using @Spy and @Autowired together

#1
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.

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

#2
I know about these two options:

1. Use [@SpyBean][1] annotation from spring-boot-test as the only annotation

<!-- language: java -->

@Autowired
@InjectMocks
private ProductController productController;

@SpyBean
private ProductService productServiceSpy;

2. Use Java reflection to "autowire" the spy object, e.g. [ReflectionTestUtils][2]

<!-- language: java -->

@Autowired
private ProductController productController;

@Autowired
private ProductService productService;

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


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#3
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:

[To see links please register here]


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

#4
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

[To see links please register here]


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

#5
UPDATE 20220509-203459

For TestNg User,
Add this to the test class

> @TestExecutionListeners(listeners = MockitoTestExecutionListener.class)

and extends AbstractTransactionalTestNGSpringContextTests

then @SpyBean will work.

-----------------

Two choices are given in [this Answer][1]

Howerver, I met problems.

1. Use @SpyBean annotation from spring-boot-test as the only annotation

This seems a good idea but only for junit users. I am using TestNg in my tests.
I have not found a way to make @SpyBean work well with TestNg.

2. Use Java reflection to "autowire" the spy object, e.g. ReflectionTestUtils

The beans autowired seem all have final methods, because spring have already proxy them and make methods final. So Mockito.spy a autowired bean maybe impossible.

Indeed, i tried and got a exception:

> invalid use of argument matchers 0 matchers expected 1 recorded

I didnot find reason myself but i saw explanation [from here][2]


So, the only approach left is

[To see links please register here]


I am not sure if it does work, I will try.
-- tried,not work. maybe because the method parameter is also spring proxied. The methods are alse final.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#6
I have a similar problem and we fixed using @SpyBean and @Autowired together:

@SpyBean
@Autowired
ClosedInvoiceEventHandler closedInvoiceEventHandler;
Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through