Hello,
I am writing a JUnit 5 extension.
public void beforeAll(ExtensionContext extensionContext) { .. }
My custom code is being called, which is awesome.
But I can't seem to find a way to have a callback for methods marked with @BeforeAll.
But I can't seem to find a way to have a callback for methods marked with
@BeforeAll.
There are not any extension APIs that receive callbacks for the invocation of user-supplied lifecycle methods such as @BeforeAll, @BeforeEach, etc.
Generally speaking, an extension should not be concerned with whether or not a user implements custom lifecycle methods. Their presence or absence should in no way influence the behavior of an extension.
So why do you feel that you need a callback for such scenarios?
Regarding the title of this issue ("Access method name in beforeAll extension point"), what "method name" do you wish to access?
FWIW we might add such a callback in #157.
My goal is to generate an HTML/ReactJS test report using data collected from the test runs. On a test side use a framework that tracks executed Test Steps. My JUnit extension associates test steps with each test and let users explore what happened during each test after tests are ran.
I want "init" part and correspondent Test Steps to be present in the generated report as well.
Right now I put a hack and simply associate each Test Step outside a test method with an "init".
Ideally I want to know what steps happened during each @BeforeAll and use methodName in place of "Init" in the generate report.
OK. So it's just for reporting purposes.
In that case, it might make sense to add "events" to the TestWatcher API for user-supplied lifecycle methods.
@junit-team/junit-lambda, Thoughts?
Tentatively slated for 5.5 M1 for the purpose of _team discussion_.
Team Decision: Implement #157 first and see if that can reasonably be used to implement the use case described in this issue.
Hello @marcphilipp, was there any decision made?
Anything I can help with?
@MykolaGolubyev The new InvocationInterceptor extension point should allow you to do what you need:
public class MyExtension implements InvocationInterceptor {
@Override
public void interceptBeforeAllMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
String methodName = invocationContext.getExecutable().getName();
// remember methodName somewhere for tracking here
try {
invocation.proceed();
}
finally {
// forget methodName again here
}
}
}
@MykolaGolubyev Please let us know if that works for you so we can close the issue. 🙂
@marcphilipp this is a very nice new addition to the API! Thank you for pointing it out.
Currently when I wrap regular @Test methods via beforeEach(ExtensionContext extensionContext) I am able to get the provided display name using ExtensionContext::getDisplayName. Is there a way to get provided display name of @BeforeAll?
@BeforeAll methods don't have display names so I'm not following. Could you clarify what you need, maybe with an example?
I was trying to use @DisplayName on top of @BeforeAll
@BeforeAll
@DisplayName(“create customers”)
public static void create() { ... }
That's not read by Jupiter, but you could read it from the method in the InvocationInterceptor:
var method = invocationContext.getExecutable();
var name = AnnotationSupport.findAnnotation(method, DisplayName.class)
.map(DisplayName::value)
.orElseGet(method::getName)
@marcphilipp oh of course! Thanks again. Didn't realize that @BeforeAll and @DisplayName combo is not part of the framework standard combo.
Closing this ticket.