Reputation: 12678
The documentation for @RegisterExtension
mentions something about injection of the instance:
the extension will be registered after the test class has been instantiated and after all
TestInstancePostProcessor
s have been given a chance to post-process the test instance (potentially injecting the instance of the extension to be used into the annotated field).
Are there any post-processors in JUnit which can do this for extensions automatically, or is this just talking about things people might build in the future?
In our case, I found that many of our extensions turn out to be like this:
@RegisterExtension
public final TempFolderExtension temp = new TempFolderExtension();
@RegisterExtension
public final SomeFactoryExtension factory = new SomeFactoryExtension(temp);
A container like PicoContainer could automatically figure out how to construct the instances.
It would be really nifty if we could just write,
@RegisterExtension
public TempFolderExtension temp;
@RegisterExtension
public SomeFactoryExtension factory;
And either an annotation processor or a runtime injector could fill in the rest.
Dependencies between this sort of extension also has implications for the order they should run in.
Upvotes: 3
Views: 1987
Reputation: 3296
I don't know if such an extension exists. I think it is more common in the JUnit 5 ecosystem to register extensions with @ExtendWith
. The extension can then inject interfaces into the test.
@ExtendWith(TempFolderExtension.class)
static final class SomeTest {
public TempFolderInterface temp;
@Test
void test() {
...
}
}
However, if you want to have an extension as proposed in the question, it would be simple to implement one. Here is ExtensionInjector
, a working implementation for such extension.
final class ExtensionInjector implements TestInstancePostProcessor {
@Override
public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
List<Field> fields = ReflectionSupport.findFields(
testInstance.getClass(),
field -> AnnotationSupport.isAnnotated(field, RegisterExtension.class),
HierarchyTraversalMode.BOTTOM_UP);
for (Field field : fields) {
field.trySetAccessible();
if (field.get(testInstance) == null) {
field.set(testInstance, ReflectionSupport.newInstance(field.getType()));
}
}
}
}
You can add this extension to your project as documented in the JUnit 5 User Guide.
Upvotes: 1
Reputation: 49
Short answer: No, it is not possible, when using @RegisterExtension
you have to construct your extension instance manually.
Read https://junit.org/junit5/docs/current/user-guide/#extensions 5.2.2
Upvotes: 0