Introduce extension API to handle exceptions from test class constructors
Overview
Let's assume I need to load and initialize some properties in the class ones for all tests and nested tests. I can do this in the class constructor when @TestInstance(Lifecycle.PER_CLASS) or in static-block. @BeforeAll lifecycle method is not applicable for this purpose, because it is invoked one time for main class and so many times how many nested (@Nested) classes we have, even when @TestInstance(Lifecycle.PER_CLASS).
Since it's bad practice to include the code potentially throwing exception in static-block, we will not load and initialize properties in static-block.
Only solution is to load and initialize properties in the class Constructor. And, of course, I need to log in my report any exceptions thrown during running test class including exceptions thrown in the class constructor. Moreover I need to capture actual state of application when this exception is thrown, like it has been handled in this feature request https://github.com/junit-team/junit5/issues/1454.
Unfortunately I didn't find exception handler for the exceptions thrown in the class Constructor. I was looking for it in org.junit.jupiter.api.extension package, because other lifecycle methods exception handlers are located there.
Proposal
Introduce additional exception handler APIs which will be invoked for exceptions thrown in the class constructor. This make it possible to handle exceptions and take application screenshots at the correct point in time.
Test class example:
@TestInstance(Lifecycle.PER_CLASS)
@ExtendWith(LoggerExtension.class)
class Example {
public Example() {
System.out.println("Constructor execution");
throw new RuntimeException("Constructor exception");
}
@Nested
@TestInstance(Lifecycle.PER_CLASS)
public class Group {
@Test
public void grouppedTest1() {
Log.stepInfo("Groupped Test execution 1");
}
@Test
public void grouppedTest2() {
Log.stepInfo("Groupped Test execution 2");
}
}
}
And LoggerExtension will look like below:
public class LoggerExtension implements ConstructorExceptionHandler {
@Override
public void handleContructorExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
log.error("Error");
throw throwable;
}
}
Deliverables
- [ ] Introduce extension API for handling exceptions thrown in the test class constructor.
@beluha Would implementing a InvocationInterceptor and overriding interceptTestClassConstructor with a try-catch block work for you?
Hi @marcphilipp , thank you for quick solution. I just tried to implement a InvocationInterceptor with overridden interceptTestClassConstructor with a try-catch, and it definitely works for me.
Will you consider introduction of separate exception handler for the exceptions thrown in the test class constructor similar to standard approach with exception handlers for other lifecycle methods?
Team Decision: Wait for additional interest since there's an existing, viable alternative.