-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Argument passed to verify() is of type MyClassToSpy $$SpringCGLIB$$0 and is not a mock! #23
Comments
Hello, Spring boot 3 should work with no problem. Is there any way you could isolate the issue in a small snippet for me to reproduce? |
Hi @antoinemeyer, thanks for your quick response :) Unfortunately, the project is very complex, so maybe it's a problem with my setup. I am within an Maybe it's a problem, that the spied class is also injected in other classes (outside of the scope of this integration test)? I hope I will find the time to reproduce this in a smaller project in the upcoming days. |
Could you try to use version |
Hi @antoinemeyer, ok, did this but got an error when starting the test:
Did replace @SpyBean
private ConnectionBF publisher; with @SpyInBean(CallbackBF.class)
private ConnectionBF publisher; Here's the full stack trace:
|
Thank you for sharing those details. |
Yes, of course I will do. Thank you in advance! |
I have reproduced the issue with a minimal working sample, please see my repo inkassso/mock-in-bean-issue-23. What I have found, the issue occurs when The issue with this is, that when setting up a mock, Mockito seems to be unaware of any Spring proxies (and frankly why should it?) and when storing information about a mock internally in a Map, the hashCode of the proxy is used. Quite suprisingly, during the verification process, Mockito actually is aware of Spring proxies. When checking, if the provided object is actually a mock, it is looking up the mock information in said Map, for which the hashCode of the object must computed. However, this time it unwraps the Spring proxy beforehand (even through the outer spy), because it's expecting the spy to be within the proxy, not outside. Of course, the hashCode of actual service instance is different than the one of the proxy, under which the information is actually stored. To Mockito, that failed lookup means, that the provided object is not a spy or mock, even though it clearly is. Please take a look at the testcases. I also included a test with a workaround, which removes the proxy (and any interceptors with it). Also, |
Thank you @antoinemeyer, this was a very impressive piece of reverse-engineering. |
Thank you, @spyro2000. As to why Mockito unwraps the proxy, it's a customization by Spring only applied in the verification step, see SpringBootMockResolver. Regarding mock creation and why that isn't necessary with However, the proxy target can be set using reflection, just like this library injects the spy into the target service. I added another testcase where the proxy is unwrapped and instead of injecting the spy directly into the target service, it is injected in the wrapping proxy. The target service keeps the reference to the proxy and when the proxy is invoked, it invokes the spy, which then invokes the actual service instance. Works like a charm, and while it isn't as elegant, eventually the service vs. spy structure is the same as with Spring's |
Thanks @inkassso for providing the analysis and a reproducible test case. A solution would be to distinguish the original value from the mockable value which would be that proxy containing the ultimate target. I opened #28 with suggested changes. I added a test with the test case you provided. Does that fix your issue? |
Version: boot2-v1.5.2
Spring Version: 3.1.2
Hi there,
I tried to replace a
@SpyBean
(which dirties my Spring context) with this setup:The test itself runs fine but I can't verify the call with Mockito:
This returns
Argument passed to verify() is of type MyClassToSpy $$SpringCGLIB$$0 and is not a mock!
What did I do wrong here? Is Spring Boot 3 just not supported?
Thank you!
The text was updated successfully, but these errors were encountered: