quarkus: QuarkusTransaction not working in Unit-Test since 2.16
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/transaction
Expected behavior
Unit-Test runs to completion
Actual behavior
NullpointerException is thrown
How to Reproduce?
Define Bean with TX-semantics
@Singleton
public class TxBean {
public void doStuff(){
// using deprecated version to switch between versions. New api yields the same error
QuarkusTransaction.run(() -> System.out.println("Hello TX"));
}
}
Define a unit-test
public class TxBeanTest {
@Test
public void test(){
var sut = new TxBean();
sut.doStuff();
}
}
Run it -> fails
Change version back of Quarkus to 2.15.3 Run again -> Success
Output of uname -a
or ver
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
or gradlew --version
)
Apache Maven 3.9.1
Additional information
As a workaround falling back to method annotated with @Transactional
solves the issue
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 22 (22 by maintainers)
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.
QuarkusUnitTest
is great for certain things, but it’s relatively slow compared to “just” booting the CDI container. Something like Weld JUnit, e.g.ArcTestContainer
or the ArC Arquillian adapter, would be a good fit for a lot of unit testing cases, I think.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 mean CDI dependencies.
Your bean might call a static method in Quarkus (say,
QuarkusTransaction.run
) that retrieves a CDI bean dynamically (Arc.container().whatever
). You care about that dependency, and you’ll easily notice it by running your test and looking at the failure, and then you’ll mock it.But you don’t care about that dependency’s transitive dependencies, because you mocked it, hopefully removing all transitive CDI dependencies.
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
TransactionManager
, though the API is worse (CheckedException, Commit, Rollback etc)…but only in one place which aleviates the pain a bit