quarkus: Quarkus CDI-managed beans not available in Pact state callbacks

Problem

We have a Pact REST provider test with state callbacks, where we do not want to use testcontainers to startup the application, but rather a normal @QuarkusTest. For easy use-cases this works, as mentioned in https://github.com/quarkusio/quarkus/issues/9677 and demonstrated in https://github.com/skattela/pact-workshop-jvm-quarkus. But when you need to use @State callbacks to initialize some state in your application, then you’ll find out, that you cannot use CDI-managed beans.

Investigation

I investigated this issue and found out, that with that setup we generate two different test class instances. I think this is normally also the case, but here Pact uses the instance, where Quarkus does not inject anything.

Here’s the first instance creation (which will then be used by Pact) https://github.com/quarkusio/quarkus/blob/2.6/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java#L687 A little below initTestState(extensionContext, state); is called, and it creates the “proper” instance: https://github.com/quarkusio/quarkus/blob/2.6/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java#L727

Possible solutions

Maybe we can return the actualTestInstance within interceptTestClassConstructor(). (see first comment)

Environment (please complete the following information):

  • Output of uname -a or ver: Windows 10 - Version 20H2 (Build 19042.1415)
  • Output of java -version: openjdk version "11.0.10" 2021-01-19
  • GraalVM version (if different from Java): n/a
  • Quarkus version or git rev: 2.5.0-Final
  • Build tool (ie. output of mvnw --version or gradlew --version): Apache Maven 3.8.4

Misc

_Originally posted by @JapuDCret in https://github.com/quarkusio/quarkus/issues/9677#issuecomment-1004754024_

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

Well, this is still a major issue in my opinion. The fact that it is not possible to use DI or Mockito for state callbacks are a huge disadvantage in comparison to other frameworks.

This workaround is indeed super-hacky and not working when you want to use Mockito proxy classes.

No no this is very much in the forefront! @holly-cummins and I are doing a lot of talking about Pact coming up in the next few months (https://devnexus.com/presentations/avoiding-common-pitfalls-with-modern-microservices-testing, https://www.devoxx.co.uk/talk/?id=1970, https://www.devbcn.com/talk/423678).

@holly-cummins is definitely the brains behind the operation, but it is definitely something we are continually enhancing.

“Update” is a strong word, but I have a plan-for-a-plan. The root cause of many of the issues we see where code in Pact tests loses access to Quarkus-y enhancements (like injected CDI beans) is classloading. We want the test classes to run with the Quarkus classloader, but because of the JUnit lifecycle manipulations, it ends up running in the system classloader. We’ve been a bit blocked, because there wasn’t a way to tell JUnit to use an alternate classloader. However, apparently in JUnit 5.10, that limitation is lifted. JUnit 5.10 isn’t released yet, so any fix would be a ways off, but I’m planning to start experiments to confirm we actually can switch classloaders, and see how many of these kinds of issues get fixed.