Inject returns NULL when activating jqwik in Quarkus test

208 views Asked by At

We want to introduce property-based testing into our Quarkus project, preferably with jqwik. We already got numerous test cases using junit jupiter. We also use CDI in out test cases.

Getting jqwik running in a small Quarkus example project went well, so I wanted to write some properties in out big project. jqwik is running, however, the @Property, @Example and @Provider methods do not have access to the injected bean (as in: the injected bean is Null, TreeRepository in the example below). Same for ArbitrarySupplier subclasses. If I replace the @Example with a @Test the referring test can access the bean and the test passes.

My first guess is that this has something to do with the jqwik lifecycle. I did not find enough information about how (and if?) jqwik integrates with injection. How do I get this running?

In the example I expect treeRepository to be an instance of TreeRepository (the class is @ApplicationScoped). Instead it is null, except for in the method with the @Test annotation.

@QuarkusTest
class MyTestClass {


  @Inject
  TreeRepository treeRepository;

  
  @Test
  void testSimple() {
    final Collection<Tree> trees = this.treeRepository.getTrees() // works
    assertThat(trees).isNotEmpty(); 
  }


  @Example
  void testSimple() {
    final Collection<Tree> trees = this.treeRepository.getTrees() // does not work
    assertThat(trees).isNotEmpty(); 
  }

  @Property
  void treesHaveLeaves(@Forall("tree") Tree tree) { // does not work
    assertThat(tree.getLeaves()).isNotEmpty(); 
  }

  Arbitrary<Tree> tree() {
    final Collection<Tree> trees = this.treeRepository.getTrees(); // does not work
    return Arbitraries.of(trees);
  }
}
1

There are 1 answers

3
johanneslink On

There is bad news and maybe a bit of good news.

The bad news: @QuarkusTest is specially made for use with JUnit Jupiter. Jupiter and jqwik are two different test engines for the JUnit Platform. The lifecycles of different engines do not compose, that's why treeRepository will not be injected automatically when you're executing jqwik properties or examples.

The good news is that it's probably not too difficult to create something like @JqwikQuarkusTest for your integration of jqwik and Quarkus. If you want to do that yourself you can use jqwik's Spring support as an inspiration or template: https://github.com/jlink/jqwik-spring. Or you read up about jqwik's hooks here: https://jqwik.net/docs/current/user-guide.html#lifecycle-hooks and start from scratch.

If you don't feel up to the task yourself, you might want to think about paying someone to do it for you or your company. I'd be happy to help out.