3

I have @QuarkusTest based test class. And I want to implement a JUnit 5 extension (BeforeEachCallback, AfterEachCallback) that interacts with a specific bean of my Quarkus test context. I tried CDI.current(), but that results into: java.lang.IllegalStateException: Unable to locate CDIProvide

In Spring based test for example I access the ApplicationContext via

@Override
  public void beforeEach(final ExtensionContext extensionContext) {
    final ApplicationContext applicationContext = SpringExtension.getApplicationContext(extensionContext);
    MyBean myBean = applicationContext.getBean(MyBean.class);
}

which I can then use to programmatically query concrete beans from my test context. Is there any kind of similar approach to Quarkus tests? I mean, I can @Inject the bean into my test class and access it in a @BeforeEach method, but I am looking for a more 'reusable' solution.

Thank you very much.

Philipp Li
  • 499
  • 6
  • 22
  • 1
    Have you tried the method in https://quarkus.io/guides/getting-started-testing#enrichment-via-quarkustestcallback? – geoand Jun 03 '22 at 12:48
  • Thank you for the hint. It looked promising at first. But I also with QuarkusTestBeforeEachCallback / QuarkusTestMethodContext I can't find a way to access beans of my Quarkus application. – Philipp Li Jun 03 '22 at 20:57
  • CDI.current() works fine with those callbacks. So its actually an working approach to solve my problem. :) – Philipp Li Jun 03 '22 at 21:08
  • 1
    Mind adding an answer to your own question? That will help future readers – geoand Jun 09 '22 at 08:52

1 Answers1

4

geoand put me on the right track. A valid approach would be to use QuarkusTestBeforeEachCallback / QuarkusTestMethodContext.

So given my custom QuarkusTestBeforeEachCallback implementation which now supports accessing quarkus beans via CDI:

public class MyBeforeEachCallback implements QuarkusTestBeforeEachCallback {

    @Override
    public void beforeEach(QuarkusTestMethodContext context) {
        if (Stream.of(context.getTestInstance().getClass().getAnnotations()).anyMatch(DoSomethingBeforeEach.class::isInstance)) {
            final Object myBean = CDI.current().select(MyBean.class)).get()
            // ... do something with myBean
        }
    }

    @Retention(RetentionPolicy.RUNTIME)
    public @interface DoSomethingBeforeEach {
        // ...
    }
}   

and a service declaration file

src/test/resources/META-INF/services/io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback

with the content

com.something.test.MyBeforeEachCallback

I now can use it in my @QuarkusTest tests e.g:

@QuarkusTest
@DoSomethingBeforeEach
public abstract class AbstractV2Test {

// ...

}

This is a bit more complicated than what we are used to with Spring Boot tests, but it definitely works.

Philipp Li
  • 499
  • 6
  • 22