-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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 mock EntityManager
anymore
#16437
Comments
Might be fixed already by #16341? |
Ah yes indeed. We still have to add a test for it, though. |
No, this is what I get now:
But the underlying issue is:
So there's a combination of failure from ORM and mocking setup. |
This is way above anything I can comprehend. I've pushed a reproducer at https://github.com/FroMage/quarkus/tree/16437 I don't know if this is more of an issue for @yrodiere @Sanne @geoand or @mkouba but I think it is probably important, not just for Panache, since I don't think we can mock |
Repro is |
@FroMage The transaction-scoped EntityManagers are now exposed as Sessions as well, so that people can use In any case... maybe try this?
Not saying that's a long-term solution, but if it works that's at least a workaround. |
Ok I should have read the rest of the thread... So no, I have no idea what's going on :] |
it's a feature! :) |
I'll have a look tomorrow |
Thanks! |
FWIW, you can also do something like this with Mockito: Mockito.mock(ForwardingSession.class, withSettings().extraInterfaces(EntityManager.class)); |
@FroMage I pushed a couple of commits to: https://github.com/geoand/quarkus/tree/16437 It does make mocking work, but the test still doesn't pass because you (hopefully) need to mock the required EntityManager methods in the test like you did for |
Thanks! |
Well I'm actually getting this exception now, which makes no sense, unless Mockito isn't able to implement that method for some reason:
|
Did you try to mock that method? |
Oh hold on. So yeah, I did mock it (and it's not getting called), but also, this isn't the mock that fails to implement it: it's the Huh, it's a covariant method |
How do I reproduce the issue in few steps? |
Ok, so I was able to reproduce the problem. Yes, the client proxy class declares |
Sorry about the delay. OK so it's an ArC bug then? |
I'm not sure TBH because I would expect the hibernate |
Hm, it seems that all other @Sanne do you happen to know why |
no sorry I don't know if there's a specific reason. |
BTW it's defined in |
Ok, so I was finally able to create a reproducer. To sum it up:
This PR: #16671 should fix this problem. |
Thanks a lot. This allows me to move further. Now I run into this weird thing:
When I'm doing this: @QuarkusTest
public class PanacheMockingTest {
@Inject
Session session;
@BeforeAll
public static void setup() {
Session mock = Mockito.mock(Session.class);
Query mockQuery = Mockito.mock(Query.class);
Mockito.doNothing().when(mock).persist(Mockito.any());
Mockito.when(mock.createQuery(Mockito.anyString())).thenReturn(mockQuery);
Mockito.when(mockQuery.getSingleResult()).thenReturn(0l);
QuarkusMock.installMockForType(mock, Session.class);
}
@Test
@Order(1)
public void testPanacheMocking() {
...
// THIS THROWS
Mockito.verify(session).persist(Mockito.any());
}
} In other injection points, I do get the proper mock I'm pretty sure https://quarkus.io/guides/getting-started-testing#quarkus_mock says this should work, no @geoand ? |
@FroMage you are verifying the session when you should verifying the mock :) Something like: @QuarkusTest
public class PanacheMockingTest {
@Inject
Session session;
static Session mock;
@BeforeAll
public static void setup() {
mock = Mockito.mock(Session.class);
Query mockQuery = Mockito.mock(Query.class);
Mockito.doNothing().when(mock).persist(Mockito.any());
Mockito.when(mock.createQuery(Mockito.anyString())).thenReturn(mockQuery);
Mockito.when(mockQuery.getSingleResult()).thenReturn(0l);
QuarkusMock.installMockForType(mock, Session.class);
}
@Test
@Order(1)
public void testPanacheMocking() {
...
Mockito.verify(mock).persist(Mockito.any());
}
} |
But… the docs I pointed to indicate that even in the test, the |
I don't think you can use |
OOOOOOOHHH OK. So… OK. So what happens is that And even though you can call the methods of both the mock instance and the proxy to the mock, in order to get mock responses, you can actually only call OK. That's a subtlety that I'll add to the guide, because that's quite a fine one IMO. |
But thanks for your explanation! |
@FroMage exactly |
Interesting, but this is rather tricky for end users. Couldn't the CDI proxy be made to work with |
I personally don't think it's tricky - it's just how mockito works. |
Or resort to Got that from here: https://quarkusio.zulipchat.com/#narrow/stream/187038-dev/topic/Unproxy.20.40RequestScoped.20bean/near/219501112 |
Huh, so perhaps I used the wrong approach in my test? |
What is you exact goal? |
Sure but isn't that always the answer :) "There's a memory leak X" --> "That's just how this works" :-P What I'm suggesting is that it's not obvious to users that when they inject an object they get a proxy. And sure they're mocking here so a proxy is expected, but I guess that having a proxy of a proxy isn't the general expectation. But I'm entirely out of my field of comfort, so no idea if it's easy - just saying if we could have ArC generate the proxy while maintaining its mock superpowers that would be more useful IMO. No idea if there's drawbacks. |
Sure, making users lives easier is what we strive to do. |
@geoand you're so right, sorry about this. I'll update my test and my docs to use it, that is indeed much simpler. |
Glad to hear it! |
Done. |
Sorry for the archeology work, Is this fix specific to this scenario, or was there any regression or change since then? I'm facing the same issue with Code from docs (https://quarkus.io/version/3.8/guides/hibernate-orm-panache#mocking-entitymanager-session-and-entity-instance-methods) shows some warnings for Even when doing some manual casting with my code, I'm getting the following error ERROR:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Query$MockitoMock$JX88Svnf cannot be returned by createNativeQuery()
createNativeQuery() should return NativeQuery
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hibernate.Session;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
@QuarkusTest
class InjectionRepositoryTest {
@InjectMock
Session session;
@BeforeEach
public void setup() {
Query mockQuery = Mockito.mock(Query.class);
Mockito.doNothing().when(session).persist(Mockito.any());
Mockito.when(session.createNativeQuery(Mockito.anyString())).thenReturn(mockQuery);
Mockito.when(mockQuery.getSingleResult()).thenReturn(0l);
}
@Test
void testPanacheMocking() {
assertEquals(1, 1);
}
} Fails when importing Is this expected (the warnings and the usage of different types)? Should I create a new issue? |
Yes please. |
#15092, and more specifically https://github.com/quarkusio/quarkus/pull/15092/files#diff-dc1ed2e710fe857008635f1b3280c2adb1fc6b90b0925bd508e24d89f696050fR39 prevents me from mocking
EntityManager
:This leads to:
The text was updated successfully, but these errors were encountered: