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

QuarkusMock.installMockForInstance() does not inject the mock to the target bean [regression] #30788

Closed
rsynek opened this issue Feb 1, 2023 · 9 comments
Labels
area/testing kind/bug Something isn't working

Comments

@rsynek
Copy link
Contributor

rsynek commented Feb 1, 2023

Describe the bug

The QuarkusMock.installMockForInstance() does not seem to work anymore with the Quarkus main. With 2.16.0.Final, the QuarkusMock works as expected.

See the reproducer (requires 999-SNAPSHOT of Quarkus):
https://github.com/rsynek/quarkus-mock-reproducer

Expected behavior

Install the mock into the @Inject field.

Actual behavior

The @Inject field contains the normal instance, not the mock.

How to Reproduce?

https://github.com/rsynek/quarkus-mock-reproducer

Output of uname -a or ver

Linux 5.15.0-58-generic #64~20.04.1-Ubuntu

Output of java -version

Java version: 17.0.5, vendor: Eclipse Adoptium,

GraalVM version (if different from Java)

No response

Quarkus version or git rev

No response

Build tool (ie. output of mvnw --version or gradlew --version)

apache-maven-3.8.3

Additional information

Maven home: /opt/maven/apache-maven-3.8.3
Java version: 17.0.5, vendor: Eclipse Adoptium, runtime: /home/rsynek/.sdkman/candidates/java/17.0.5-tem
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-58-generic", arch: "amd64", family: "unix"

@rsynek rsynek added the kind/bug Something isn't working label Feb 1, 2023
@gsmet gsmet added area/arc Issue related to ARC (dependency injection) area/testing and removed triage/needs-triage labels Feb 1, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Feb 1, 2023

/cc @geoand (testing), @manovotn (arc), @mkouba (arc)

@geoand
Copy link
Contributor

geoand commented Feb 2, 2023

@mkouba @manovotn are they any Arc changes that could have broke this?

The weird thing is that none of our tests have broken

@manovotn
Copy link
Contributor

manovotn commented Feb 2, 2023

@mkouba @manovotn are they any Arc changes that could have broke this?

The weird thing is that none of our tests have broken

None that I am aware of, this should be handled by code inside proxies and I don't think that changed.
Also, the test that we have (link) seems very similar to what's done in the reproducer.

@Ladicek
Copy link
Contributor

Ladicek commented Feb 2, 2023

I suspect this particular reproducer fails due to the Mockito 5 changes (#30710, #30730, #30761). Just look at what Mockito.mock(MyBean.class) returns, no dependency injection involved.

Could you please share your specific problem?

@Ladicek
Copy link
Contributor

Ladicek commented Feb 2, 2023

With the present reproducer, it is actually fairly easily to demonstrate that mocking in ArC in fact still works. Here's a diff:

diff --git a/src/main/java/org/example/MyClass.java b/src/main/java/org/example/MyClass.java
index c0ec974..12f4424 100644
--- a/src/main/java/org/example/MyClass.java
+++ b/src/main/java/org/example/MyClass.java
@@ -1,4 +1,8 @@
 package org.example;
 
 public class MyClass {
+    @Override
+    public String toString() {
+        return "normal";
+    }
 }
diff --git a/src/test/java/org/example/MockTest.java b/src/test/java/org/example/MockTest.java
index 8a2d126..dd9da71 100644
--- a/src/test/java/org/example/MockTest.java
+++ b/src/test/java/org/example/MockTest.java
@@ -20,10 +20,11 @@ public class MockTest {
 
     @Test
     void mockingWorks() {
+        MyClass myClassMock = mock(MyClass.class);
+        when(myClassMock.toString()).thenReturn("mocked");
         MyBean myBeanMock = Mockito.mock(MyBean.class);
-        // OptaPlanner detects the mock is not the class nor subclass of the PlanningSolution.
-        when(myBeanMock.getMyClass()).thenReturn(mock(MyClass.class));
+        when(myBeanMock.getMyClass()).thenReturn(myClassMock);
         QuarkusMock.installMockForInstance(myBeanMock, myBean);
-        assertThat(myBean.getMyClass().getClass().getName()).contains("$MockitoMock");
+        assertThat(myBean.getMyClass().toString()).isEqualTo("mocked");
     }
 }

@rsynek
Copy link
Contributor Author

rsynek commented Feb 2, 2023

There is a negative test making sure that a proper error message is returned. To trigger the error path, I use Mockito to pass there a proxy class instead of the original class, which is detected.

From what I read here is that with Mockito 5 this behavior has changed.

@Ladicek
Copy link
Contributor

Ladicek commented Feb 2, 2023

Yeah, Mockito 5 seems to create mocks differently. I'm removing the area/arc label.

EDIT: see also https://github.com/mockito/mockito/releases/tag/v5.0.0

@Ladicek Ladicek removed the area/arc Issue related to ARC (dependency injection) label Feb 2, 2023
@geoand
Copy link
Contributor

geoand commented Feb 2, 2023

Is there still something we need to do about this one?

@manovotn
Copy link
Contributor

manovotn commented Feb 2, 2023

I don't think we can do much. It's a behavior change in Mockito but as Ladislav showed, mocking as such still works.

I suspect in the example @rsynek showed, they're only using Mockito to get a proxy. They need to either adjust the test or force Mockito to use the old way of generating mocks (according to release notes it's possible but I am not sure how, didn't look further).

@geoand geoand closed this as completed Feb 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/testing kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants