-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce EnableTestScopedConstructorContext
annotation for extensions
#4032
Conversation
see #3445 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I introduced the annotation @EnableTestScopedConstructorContext
to enable the new behavior for TestInstancePreConstructCallback
, TestInstancePostProcessor
and TestInstanceFactory
. I have few remaining questions, which I have added as review comments.
...er-api/src/main/java/org/junit/jupiter/api/extension/EnableTestScopedConstructorContext.java
Show resolved
Hide resolved
@Retention(RetentionPolicy.RUNTIME) | ||
@Inherited | ||
@API(status = MAINTAINED, since = "5.12") | ||
public @interface EnableTestScopedConstructorContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to suggest other names. This is the best name that came to mind. I think the name is good enough, at least I like it much more than my other ideas (e.g. NewTestInstanceConstructionContext
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that you have already suggested @MethodLevelExtensionContextAware
. I don't have a strong preference. Your suggestion is a bit shorter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick with your name for now. I'll brainstorm with the team in our next team call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanted to note, that after the idea of a common method has lingered in my head over the last day, I have started to prefer it. The idea would be to add a default method to the empty Extension
interface. At the end, I don't think any of my reasons is that significant, and I am totally happy with the current solution as well. Anyway, here are the reasons why I started to like the idea of a default method, although it is more clunky to use.
- Improved discoverability as the method is shown by the IDE when you look for methods to override (e.g. Ctrl+I in IntelliJ). However, the Javadoc also makes it rather easy to find already.
- Extensions can use arbitrary logic for the flag. For example, a wrapper or proxy which delegates all method calls to another extension would be able to preserve the flag from the delegate. However, it is probably a very special use case and not that relevant.
- Less likely to impact the performance without having to introduce any cache.
- Maybe more consistent, as I think there are currently no other annotations used in the extension logic.
- A default method could technically be removed again without breaking binary compatibility (ABI). However, I assume removing it from the API again is not really an option anyway, so it is not really relevant.
Feel free to pick whatever you prefer. I just wanted to communicate my thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are good points! To get a better feel for it, I've given it a try in #4062. I may be subject to the IKEA effect now, but it like the solution better for the reasons you've given above.
...piter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java
Outdated
Show resolved
Hide resolved
...piter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java
Outdated
Show resolved
Hide resolved
...piter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java
Outdated
Show resolved
Hide resolved
...piter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java
Outdated
Show resolved
Hide resolved
@Retention(RetentionPolicy.RUNTIME) | ||
@Inherited | ||
@API(status = MAINTAINED, since = "5.12") | ||
public @interface EnableTestScopedConstructorContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick with your name for now. I'll brainstorm with the team in our next team call.
...er-api/src/main/java/org/junit/jupiter/api/extension/EnableTestScopedConstructorContext.java
Show resolved
Hide resolved
b92393c
to
6cda95f
Compare
EnableTestScopedConstructorContext
annotation for extensions
I'm going ahead with merging this PR. I will address the remaining work in #4057. |
Thanks a lot, @JojOatXGME! 👍 |
Also thanks from my site. I am happy to remove my workaround in my projects once it is released. 😄 Feel free to reach out if you have any questions, otherwise I will just leave it to you now. |
Overview
Resolve #1568.
Resolve #2970.
Resolve #3445.
This PR moves the instance creation into the execution context of the test method. This affects the following callbacks:
TestInstancePreConstructCallback
TestInstanceFactory
ParameterResolver
(when resolving parameters for the constructor)TestInstancePostProcessor
Assuming the test is using
TestInstance.Lifecycle.PER_METHOD
(the default), these callbacks will now receive theExtensionContext
for the currently executed test method. This has the following effects:ExtensionContext.getTestMethod()
ExtensionContext.getTestClass()
andTestInstanceFactoryContext.getTestClass()
are no-longer interchangeableExtensionContext.getTestClass()
now returns the (nested) class of the currently executed testCloseableResource
which are added to the store will now be closed at the end of the test executionIf the test is using
TestInstance.Lifecycle.PER_CLASS
, the behavior is unaltered.Not sure if the change is considered API breaking. The previous behavior was rather unintuitive and not explicitly documented. However, the example at
TestInfoDemo
is no-longer valid and has been changed as part of the PR. I also think there is a good chance that there are a few extensions in the wild which rely on the previous behavior, since the behavior was in place for multiple years. I would therefore like to know how I should proceed with the PR.I hereby agree to the terms of the JUnit Contributor License Agreement.
Definition of Done
@API
annotations