Skip to content

Support for @InjectMock EntityManager #40807

Open
@yrodiere

Description

Description

While @InjectMock Session works fine to mock the Hibernate ORM session, oddly @InjectMock EntityManager doesn't, even if a given test only uses EntityManager (e.g. using Panache): any method you'll mock will fail because something expect you to use the Session return type, even though you're mocking a EntityManager object (see stracktrace near the bottom).

This is a bit counter-intuitive, so we should probably look into either making @InjectMock EntityManager work correctly, or documenting the limitation and adding clear exception messages when someone tries to do @InjectMock EntityManager ("@InjectMock doesn't work with EntityManager, use Session instead").

Stacktrace from: #40475 (comment)

...
[INFO] Running <redacted>.XXXRepositoryTest
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.619 s <<< FAILURE! -- in <redacted>.XXXRepositoryTest
[ERROR] <redacted>.XXXRepositoryTest.testPanacheMocking -- Time elapsed: 0.113 s <<< ERROR!
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:

Query$MockitoMock$wgzFLNsQ cannot be returned by createNativeQuery()
createNativeQuery() should return NativeQuery
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
   Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

        at <redacted>.XXXRepositoryTest.setup(XXXRepositoryTest.java:32)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:1013)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptBeforeEachMethod(QuarkusTestExtension.java:808)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

2024-05-17 09:51:33,690 INFO  [io.quarkus] (main) <redacted> stopped in 0.107s
[INFO] 
[INFO] Results:
[INFO]
[ERROR] Errors: 
[ERROR]   XXXRepositoryTest.setup:32 WrongTypeOfReturnValue 
Query$MockitoMock$wgzFLNsQ cannot be returned by createNativeQuery()
createNativeQuery() should return NativeQuery
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
   Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

[INFO]
[ERROR] Tests run: 14, Failures: 0, Errors: 1, Skipped: 0
...

PS: Doesn't work with doReturn(entityManager).when(solicitudRepository).getEntityManager(); neither.

Implementation ideas

No response

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions