2

JUnit 5 seems to heavily recommend not using inheritance to share test logic and instead says to use Extensions.

So we're refactoring things into extensions.

Something I frequently see is a large number of tests programmatically adding the same three extensions. (All three of them are the kind of extension which has to be programmatically added due to their nature...)

I could implement a base class which adds these three extensions, but then I'm using inheritance again.

Is there a better way?

e.g., something like this would be nice:

public class AcmeTestExtension implements Extension {
    @RegisterExtension
    public final Extension1 extension1 = new Extension1();

    @RegisterExtension
    public final Extension2 extension1 = new Extension2();

    @RegisterExtension
    public final Extension3 extension1 = new Extension3();

    // can add methods here which delegate through to individual extensions
}

public class MyTest {
    @RegisterExtension
    public final AcmeTestExtension extension = new AcmeTestExtension();
}
Hakanai
  • 12,010
  • 10
  • 62
  • 132
  • You could group annotations into composed annotations like this https://stackoverflow.com/questions/58858912/junit5-give-dependencies-between-extension#70769120 – michid Jan 19 '22 at 10:44
  • @michid that's useful for the case where the extensions don't have state, just not for the case in my own question where they do. The best idea I currently have for the stateful case is making another extension which explicitly initialises the individual extensions... – Hakanai Jan 20 '22 at 21:35
  • I'd not rely on instance state anyway. See https://junit.org/junit5/docs/current/user-guide/#extensions-keeping-state: "Usually, an extension is instantiated only once". Which means you don't have control over when and how many instances of an extension are created. Your best bet is likely to use the extension store to explicitly store and share your state. – michid Jan 21 '22 at 10:49
  • @michid some extensions hold a resource though, where you want to use that resource in the test. e.g., a database connection, a temp directory. – Hakanai Jan 22 '22 at 09:30
  • > some extensions hold a resource Isn't that the perfect match for the store? Implement `CloseableResource` to manage the lifecycle for the resource and make the resource available to test methods via a parameter resolver. – michid Jan 22 '22 at 11:18
  • 1
    @michid sounds like it would work for some of our extensions (but could be a huge rewrite), but then not for others. Most of them still work in the simpler way, using `@RegisterExtension`. – Hakanai Jan 24 '22 at 07:56

0 Answers0