-
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
QuarkusTransaction not working in Unit-Test since 2.16 #32067
Comments
Sample |
cc @yrodiere |
Thanks for the report. This is probably a consequence of #31036 .
Can you quote the exact sentence that gives this impression? I may need to clarify that. Regardless, in your case the problem is not that no TX or TX manager is available; the CDI container, and with it the whole Quarkus infrastructure, is missing. Presumably, this was working before because we relied on some static methods to get the transaction manager, and for some reason there was a transaction manager in your environment. I suppose we could default to @geoand @mkouba , WDYT? Should we try to support that kind of things to any extent? |
See https://quarkus.io/guides/transaction#why-always-having-a-transaction-manager
I was curious how this actually can work in a unit-test at all, since as you said you need a container. On the other hand, Quarkus does a lot of compile-time magic so I expected that the container call is replaced with some no-op when running in a test. I actually prefer this style of managing transactions when fine grained control is needed. In JEE you always need to create an additional proxied method (and you can get lost in transactions if you are not careful) or inject |
Ah, I see. I don't think this referred to unit tests since it mentions "because all of these are Quarkus applications". A unit test is not a Quarkus application, that's kind of the point of a unit test. I think this was more aimed at people who think JTA is hard to set up... Though I can't say for sure, I'm not the author of these lines.
I tend to agree... If we start to support using any CDI-related stuff without CDI available, we'll have tons of things to adapt. And transaction management in Quarkus is very much CDI-related since we have a transaction scope in CDI. @lostiniceland I can offer two alternatives:
For 2., I'm not sure how easy it would be to start I wonder though... wouldn't it be useful in general to have a type of test where we only initialize CDI with a bunch of (mocked) beans, and developers can test their own bean in isolation? Some kind of Note that what we currently have with |
Although I get where this is coming from, I would very much prefer to avoid adding another type of test as I think it will just be too confusing for folks (not to mention that it will increase the aready heavy burden on maintaining test code). |
I fully agree.
Not so easy. Also even if we start the CDI container and provide a way to define the set of "active" application beans then how does a user find out which extension beans/services need to be mocked? Trial and error method? I'm not saying it's impossible. But it would be more than "starting a CDI container"... In any case, we should not throw a NPE but log an actionable error message if possible. |
I agree.
This is starting to sound a lot like Weld SE, or Weld JUnit :-) Is there a reason why |
Well in this specific case it's just the transaction manager, so it's relatively straightforward. And yes, worst case, for a unit test trial and error is conceivable as the scope is limited.
Well you can't easily use that in a library, for example. That's why unit tests could be useful. But yes, I mentioned it as the first solution, and it could work depending on @lostiniceland's exact situation. |
Considering the alternatives, I guess we will have to work without |
I suppose you can also build a little wrapper around |
But when putting it behind a mockable wrapper, the question remains why I should use it at all. I could then just also wrap the |
The scope is limited but you never know what other services are used in the dependency tree. Also not all extensions use CDI everywhere. |
It's a unit test, so only direct dependencies matter and they're supposed to be stubbed or mocked. So yes, you'll know what other services you need quickly enough through trial and error. Anyway... The consensus seems to be that the specific behavior requested in this should not be supported, and adding more testing extensions for actual unit tests is not desirable at the moment. So I'll close this. Thanks for the input everyone! |
I'm still a bit confused. If only direct dependencies matter then why use the CDI container at all? You could just use constructor/initializer injection points in your bean and mock anything you need... 🤷 |
I mean CDI dependencies. Your bean might call a static method in Quarkus (say, But you don't care about that dependency's transitive dependencies, because you mocked it, hopefully removing all transitive CDI dependencies. |
I still think we should have a unit testing story. We've been hearing this constantly and don't have a good answer at the moment. |
Well, it's not exactly "unit testing" but something more like "service mocking", right? Also I'm not sure that CDI is enough. I mean we would need to force all extensions/libs to use only CDI so that it's possible to mock all dependencies. For example, you would not be able to to That said, I'm not against this idea! |
One nice thing about Weld JUnit is that you can declaratively apply extensions, which lets you use e.g. MP Config easily. Unfortunately that is only possible with CDI extensions and not with Quarkus extensions -- supporting those basically amounts to the full |
Except that Quarkus config is a bit more complicated (we have
Do we actually have a relevant feature request? If not then we should create one and discuss the ideas there... |
I don't think we have a specific feature request for "unit testing", but this has been mentioned on many places over Zulip and GitHub issues. I found these 3 with just one search: |
Describe the bug
We came across a regression when moving from Quarkus 2.15.3 to 2.16.4 where the static QuarkusTransaction calls fail when running in a unit-test (without a container) giving
java.lang.NullPointerException: Cannot invoke "io.quarkus.arc.ArcContainer.instance(java.lang.Class, java.lang.annotation.Annotation[])" because the return value of "io.quarkus.arc.Arc.container()" is null
As stated in the documentation,
QuarkusTransaction
is supposed to work everywhere, using a no-op when no TX is available. see https://quarkus.io/guides/transactionExpected behavior
Unit-Test runs to completion
Actual behavior
NullpointerException is thrown
How to Reproduce?
Define Bean with TX-semantics
Define a unit-test
Run it -> fails
Change version back of Quarkus to 2.15.3
Run again -> Success
Output of
uname -a
orver
No response
Output of
java -version
openjdk version "17.0.6" 2023-01-17
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.16.4
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.9.1
Additional information
As a workaround falling back to method annotated with
@Transactional
solves the issueThe text was updated successfully, but these errors were encountered: