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

Cannot inject a generic mock in a superclass #3019

Open
julien-breda opened this issue May 25, 2023 · 4 comments
Open

Cannot inject a generic mock in a superclass #3019

julien-breda opened this issue May 25, 2023 · 4 comments

Comments

@julien-breda
Copy link

Hello !

The context

I'm trying to update Mockito from version 1 to 5.3.1 (there's some work to do)
I'm facing an issue and I built a tiny project to illustrate it : mockito-upgrade.zip

The environment

I'm using OpenJDK 11.0.14.1, Maven 3.6.1, JUnit 4.11, on Windows 10.

The code

There's an EntryPoint extending AbstractGenericClass. This last one uses a ParameterizerInjectedObject. The class Something was only created to specify generics.
When I try to test EntryPoint, with EntryPointTest, I uses Mockito to inject a mock of ParameterizerInjectedObject in my EntryPoint instance.

The problem

The problem is that the mock isn't injected.
If I remove all generics it works but this is not an acceptable solution.

If you run my test you'll have a NPE because AbstractGenericClass.object isn't initialized : it is intended to demonstrate the problem.
If you initialize it by replacing
private ParameterizedInjectedObject<T> object;
with
private ParameterizedInjectedObject<T> object = new ParameterizedInjectedObject<>();

you'll see the following failure :

Wanted but not invoked:
injected.init();
-> at test.ParameterizedInjectedObject.init(ParameterizedInjectedObject.java:7)
Actually, there were zero interactions with this mock.
at test.ParameterizedInjectedObject.init(ParameterizedInjectedObject.java:7)
at test.EntryPointTest.testInit(EntryPointTest.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:55)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:100)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:107)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:41)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)

My analyzis

When I downgrade to version 5.2.0 I'm facing this issue : #2958
The fix for this one, introduced in version 5.3.0, doesn't seem to handle my case.

I tried to debug Mockito and I think there's a problem with TypeBasedCandidateFilter, starting at line 140 when AbstractGenericClass is analyzed to see if parameter Something is valid for the injection point.

Thanks for reading,

@julien-breda julien-breda changed the title Cannot inject a generic instance in a superclass Cannot inject a generic mock in a superclass May 25, 2023
nineninesevenfour added a commit to nineninesevenfour/mockito that referenced this issue May 27, 2023
nineninesevenfour added a commit to nineninesevenfour/mockito that referenced this issue May 27, 2023
@philsttr
Copy link

philsttr commented Jun 4, 2023

I believe logstash-logback-encoder is running into this same problem.

Here's a small project (mockito-parameterized-type-injection.zip) with a unit tests that fails to inject a mock with mockito 5.3.1. The test works with mockito 5.1.1, so something regressed after 5.1.1

@thomasrichner-oviva
Copy link

I'm pretty sure I'm running into the same issue.
Interestingly it works if the generic type happens to be a String, but not if its an `Object. See minimal reproducer attached.
reproducer.zip

nineninesevenfour added a commit to nineninesevenfour/mockito that referenced this issue Sep 25, 2023
@LordMaduz
Copy link

LordMaduz commented Jan 3, 2024

I also experienced the same issue today with mockito version 5.8.0.
Interestingly, when I downgrade version back to 5.1.1 it works fine.

@melloware
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants