Skip to content
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

SpyDefinition.SpringAopBypassingVerificationStartedListener seems to handle the event parameter incorrectly. #23708

Closed
RobertZenz opened this issue Oct 15, 2020 · 11 comments
Labels
status: duplicate A duplicate of another issue

Comments

@RobertZenz
Copy link

I'm seeing the following exception when using @SpyBean for a CrudRepository in my Integration-Tests:

org.mockito.exceptions.base.MockitoException: VerificationStartedEvent.setMock() does not accept parameter which is not a Mockito mock.
  Received parameter: org.springframework.data.jpa.repository.support.SimpleJpaRepository@1adc1d78.
  See the Javadoc.
	at org.springframework.boot.test.mock.mockito.SpyDefinition$SpringAopBypassingVerificationStartedListener.onVerificationStarted(SpyDefinition.java:114)

What I'm trying to do is instrument the repository to fail at a certain call to test the error handling behavior. So the definition of the field in question is as simple as it gets:

@SpyBean
private MyCrudRepository myCrudRepository;

I can use the Spy correctly for everything, with the exception of verifying whether the function was actually called, which gives me the above exception. I'm using verify like this:

Mockito.verify(myCrudRepository, Mockito.times(1)).save(Mockito.any());

As far as I can see, that is because in SpyDefinition.SpringAopBypassingVerificationStartedListener:114 the actual object is being presented to the VerificationStartedEvent, which actually expects a mock.

Or is that an unsupported use-case or am I spying on the repository in a wrong way?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 15, 2020
@wilkinsona
Copy link
Member

Or is that an unsupported use-case or am I spying on the repository in a wrong way?

@RobertZenz, unfortunately it's hard to say as I'm not sure that I have understood exactly what you're trying to do. Could you please provide a complete yet minimal sample that reproduces the problem? You could share it with us by zipping it up and attaching it to this issue or pushing it to a separate repository on GitHub.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Nov 9, 2020
@RobertZenz
Copy link
Author

It's exactly as simple as I wrote to reproduce:

@SpringBootTest
public class Testcase {
	@SpyBean
	private MyCrudRepository myCrudRepistory;
	
	@Test
	public void test() {
		Mockito.verify(myCrudRepistory, Mockito.times(1)).save(Mockito.any());
	}
}
public interface MyCrudRepository extends CrudRepository<MyModelClass, BigDecimal> {
}

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 10, 2020
@wilkinsona
Copy link
Member

wilkinsona commented Nov 10, 2020

Thanks, but that isn't sufficient for us to be certain that we're looking at the same problem as you are seeing. For example, you haven't told us which version of Spring Boot you're using or of any other dependencies. If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. As I said above, you can share it with us by zipping it up and attaching it to this issue or pushing it to a separate repository on GitHub.

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Nov 10, 2020
@RobertZenz
Copy link
Author

Thanks, but that isn't sufficient for us to be certain that we're looking at the same problem as you are seeing. For example, you haven't told us which version of Spring Boot you're using or of any other dependencies.

Given that I've pointed you at the exact line that is the problem in HEAD, I'd say "the latest".

But I'll throw something together...

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 10, 2020
@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Nov 10, 2020
@RobertZenz
Copy link
Author

This is a simple example project which shows this exception.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 11, 2020
@wilkinsona
Copy link
Member

Thanks for the sample. It's revealed that you're using Mockito's inline mock maker, making this a duplicate of #22416.

@wilkinsona wilkinsona added status: duplicate A duplicate of another issue and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Nov 11, 2020
@ractive
Copy link
Contributor

ractive commented May 5, 2021

@wilkinsona I just ran into the same issue with spring 2.4. It seems that this issue was not a duplicate of #22416 but still exists. It seems that it's not possible to use a spring-data repository as a @SpyBean.
I have taken the example of @RobertZenz from above and updated it to spring 2.4 to show that the error still exists: https://github.com/ractive/spring-boot-gh-23708

Will you reopen this issue or shall I create a new one?

@wilkinsona
Copy link
Member

Interesting, thanks. I'll reopen it and we can take another look. There may also be some overlap with #7033. Unfortunately, @SpyBean and Spring Data JPA don't play together very nicely at the moment.

@wilkinsona wilkinsona reopened this May 5, 2021
@wilkinsona wilkinsona added status: waiting-for-triage An issue we've not yet triaged and removed status: duplicate A duplicate of another issue labels May 5, 2021
@ractive
Copy link
Contributor

ractive commented May 5, 2021

Interesting, thanks. I'll reopen it and we can take another look. There may also be some overlap with #7033. Unfortunately, @SpyBean and Spring Data JPA don't play together very nicely at the moment.

Thanks for getting into this issue again.

BTW: We're using spring-data-mongo and see exactly the same issue.

@ractive
Copy link
Contributor

ractive commented May 5, 2021

Another thing: In our case it worked with Spring Boot 2.3 and mockito 3.2.0 with:

	@SpyBean(proxyTargetAware = false)
	private MyRepository myRepository;

	@Test
	void someTest() {
		....
		verify(myRepository).findById(...):
	}

With Spring 2.4 it then fails with the following error:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type $Proxy74 and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
    verify(mock).someMethod();
    verify(mock, times(10)).someMethod();
    verify(mock, atLeastOnce()).someMethod();

	at mockfailure.MockfailureTest.test(MockfailureTest.java:18)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
.....

@wilkinsona
Copy link
Member

wilkinsona commented Jul 15, 2021

I have a possible fix for #7033 which appears to fix https://github.com/ractive/spring-boot-gh-23708. The spy is successfully created (with or without proxyTargetAware = false). The test then fails:

org.mockito.exceptions.verification.WantedButNotInvoked: 

Wanted but not invoked:
myCrudRepository.save(
    <any mockfailure.data.MyModelClass>
);
-> at mockfailure.MockfailureTest.test(MockfailureTest.java:18)
Actually, there were zero interactions with this mock.

	at mockfailure.MockfailureTest.test(MockfailureTest.java:18)

However, this is to be expected as nothing is interacting with the repository.

The test passes with a modification to the app such that MyCrudRepository.save(MyModelClass) is called.

As a result of the above, I'm going to close this one as a duplicate of #7033

@wilkinsona wilkinsona added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

4 participants