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 use InjectMock with gRCP generated classes #23618

Closed
chris-asl opened this issue Feb 11, 2022 · 12 comments · Fixed by #29266
Closed

Cannot use InjectMock with gRCP generated classes #23618

chris-asl opened this issue Feb 11, 2022 · 12 comments · Fixed by #29266
Assignees
Labels
Milestone

Comments

@chris-asl
Copy link
Contributor

chris-asl commented Feb 11, 2022

Describe the bug

We're trying to mock a gRPC client using InjectMock like so:

@InjectMock
DeviceService client;

DeviceService is one of the autogenerated gRPC classes, and specifically is defined like this
public interface DeviceService extends MutinyService.

Running the test fails with:

org.junit.jupiter.api.extension.TestInstantiationException: Failed to create test instance
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.IllegalStateException: Invalid use of io.quarkus.test.junit.mockito.InjectMock - the injected bean does not declare a CDI normal scope but: javax.inject.Singleton. Offending field is client of test class class org.project.package.DeviceGatewayTest

Since DeviceService is a Singleton, then as per the docs https://quarkus.io/guides/getting-started-testing#further-simplification-with-injectmock we should use convertScopes = true.

@InjectMock(convertScopes = true)
DeviceService client;

Doing so, produces the same error.

Expected behavior

InjectMock(convertScopes = true) should mock the generated gRPC sources, since these have Singleton scope.

Actual behavior

Tests fail with

org.junit.jupiter.api.extension.TestInstantiationException: Failed to create test instance
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.IllegalStateException: Invalid use of io.quarkus.test.junit.mockito.InjectMock - the injected bean does not declare a CDI normal scope but: javax.inject.Singleton. Offending field is client of test class class org.project.package.DeviceGatewayTest

How to Reproduce?

No response

Output of uname -a or ver

Linux homer 5.13.0-27-generic #29~20.04.1-Ubuntu SMP Fri Jan 14 00:32:30 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "11.0.13" 2021-10-19  
OpenJDK Runtime Environment (build 11.0.13+8-Ubuntu-0ubuntu1.20.04)  
OpenJDK 64-Bit Server VM (build 11.0.13+8-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.2.2.Final
(Also tested with 2.7.1.Final, still the same.)

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

Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)  
Maven home: /home/chris/.m2/wrapper/dists/apache-maven-3.8.1-bin/2l5mhf2pq2clrde7f7qp1rdt5m/apache-maven-3.8.1  
Java version: 11.0.13, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64  
Default locale: en_US, platform encoding: UTF-8  
OS name: "linux", version: "5.13.0-27-generic", arch: "amd64", family: "unix"

Additional information

No response

@chris-asl chris-asl added the kind/bug Something isn't working label Feb 11, 2022
@quarkus-bot
Copy link

quarkus-bot bot commented Feb 13, 2022

/cc @cescoffier, @michalszynkiewicz

@geoand
Copy link
Contributor

geoand commented Feb 14, 2022

I proposed on Zulip that we introduce an ASM transformation to strip the final modifier from the gRPC generated classes, thus allowing the scope conversion

@ivansenic
Copy link
Contributor

Until this is fixed, what's the way to have integration tests with gRPC clients? Is there an alternative to mocking at the moment? I tried to find documentation on this, but could not find anything?

@cescoffier
Copy link
Member

We need to be very careful with this. The final is introduced by protoc, which means that everything using protoc would expect that final. Stripping it should be done for Quarkus only.

@geoand
Copy link
Contributor

geoand commented Apr 14, 2022

Stripping it should be done for Quarkus only

Absolutely

@geoand
Copy link
Contributor

geoand commented Apr 14, 2022

Mind upload your example? I don't see which generated class is final Nevermind, I see it

@geoand
Copy link
Contributor

geoand commented Apr 14, 2022

Looked into this a little and unfortunately it's more complicated...

The most serious issue is that io.grpc.stub.AbstractAsyncStub does not have a no-args constructor... Is it possible to influence the output of protoc?

@geoand geoand added area/testing kind/enhancement New feature or request and removed kind/bug Something isn't working labels Apr 14, 2022
@cescoffier
Copy link
Member

@geoand only on the "template" we provide.

But we are coming with a more flexible solution (#24409)

@geoand
Copy link
Contributor

geoand commented Apr 14, 2022

only on the "template" we provide.

where do I find that?

@cescoffier
Copy link
Member

We only provide the mutiny template. We cannot modify the other one.
https://github.com/quarkusio/quarkus/tree/main/extensions/grpc/protoc/src/main/resources.

@geoand
Copy link
Contributor

geoand commented Apr 14, 2022

Understood. The other one is the problematic one 🥺

@cescoffier
Copy link
Member

Yes, and we need to be careful with what we will generate to avoid that situation while being close-enough from protoc

@cescoffier cescoffier self-assigned this Nov 14, 2022
cescoffier added a commit to cescoffier/quarkus that referenced this issue Nov 15, 2022
Allows mocking gRPC mutiny clients
@quarkus-bot quarkus-bot bot added this to the 2.15 - main milestone Nov 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants