quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.4k stars 2.57k forks source link

`@TestTransaction` Annotation Causes DeploymentException in Nested Test Classes #41632

Open elmodeer opened 2 weeks ago

elmodeer commented 2 weeks ago

Describe the bug

When using the @TestTransaction annotation within a nested test class, Quarkus fails to build the project and throws a DeploymentException. This issue arises because CDI rules do not allow interceptor bindings in inner classes. The error message specifically points out that the method declaring the interceptor binding must be ignored per CDI rules.

Expected behavior

The @TestTransaction annotation should be supported within nested test classes, allowing tests to run within a transaction without causing build failures.

Actual behavior

DeploymentException is thrown.

How to Reproduce?

  1. Create a Quarkus project with a nested test class structure.
  2. Annotate a test method within the nested class with @TestTransaction.
  3. Attempt to run the test.

Output of uname -a or ver

Darwin Heshams-MacBook-Pro.local 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:13:18 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6030 arm64

Output of java -version

openjdk version "21.0.1" 2023-10-17 OpenJDK Runtime Environment (build 21.0.1+12-29) OpenJDK 64-Bit Server VM (build 21.0.1+12-29, mixed mode, sharing)

Quarkus version or git rev

3.11.3

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

No response

Additional information

No response

geoand commented 1 week ago

cc @manovotn

manovotn commented 1 week ago

Hello

When using the @TestTransaction annotation within a nested test class, Quarkus fails to build the project and throws a DeploymentException. This issue arises because CDI rules do not allow interceptor bindings in inner classes. The error message specifically points out that the method declaring the interceptor binding must be ignored per CDI rules.

You are right; for interception to work, the target class needs to be a CDI bean and that is not permitted by the specification for inner classes. However, this limitation is true for any beans, not just the test structure and it is a technical limitation because of how inner-outer class relationship works. CDI container wouldn't know how to deal with instantiation, field access, possible clash of scoped between outer and inner class, destruction of outer class because its scope ends and probably more.

Note that if you, instead of inner classes, use static nested classes, all of CDI functionality works fine.

elmodeer commented 1 week ago

Hello

When using the @TestTransaction annotation within a nested test class, Quarkus fails to build the project and throws a DeploymentException. This issue arises because CDI rules do not allow interceptor bindings in inner classes. The error message specifically points out that the method declaring the interceptor binding must be ignored per CDI rules.

You are right; for interception to work, the target class needs to be a CDI bean and that is not permitted by the specification for inner classes. However, this limitation is true for any beans, not just the test structure and it is a technical limitation because of how inner-outer class relationship works. CDI container wouldn't know how to deal with instantiation, field access, possible clash of scoped between outer and inner class, destruction of outer class because its scope ends and probably more.

Note that if you, instead of inner classes, use static nested classes, all of CDI functionality works fine.

thanks for checking this out. Yeah, I thought about static inner classes but they won't help me as all the non-static test code wouldn't work.

I guess, I need to live with the fact that this is just not possible at the moment.

manovotn commented 1 week ago

Yes, the way CDI and JUnit inner class testing works doesn't really click together and don't think we can change that.

Yeah, I thought about static inner classes but they won't help me as all the non-static test code wouldn't work.

Then perhaps consider creating a test class hierarchy? I don't know your scenario but from CDI standpoint, that works and you'd be able to get access to beans, interception etc.