Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,34 +43,82 @@ available for backward compatibility.
An example implementation of `AutoCloseable` is shown below, using an `HttpServer`
resource.

[source,java,indent=0]
.`_HttpServer_` resource implementing `_AutoCloseable_`
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/extensions/HttpServerResource.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/extensions/HttpServerResource.kt[tags=user_guide]
----
--
====

This resource can then be stored in the desired `ExtensionContext`. It may be stored at
class or method level, if desired, but this may add unnecessary overhead for this type of
resource. For this example it might be prudent to store it at root level and instantiate
it lazily to ensure it's only created once per test run and reused across different test
classes and methods.

[source,java,indent=0]
.Lazily storing in root context with `_Store.computeIfAbsent_`
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/extensions/HttpServerExtension.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/extensions/HttpServerExtension.kt[tags=user_guide]
----
--
====

[source,java,indent=0]
.A test case using the `_HttpServerExtension_`
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/HttpServerDemo.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/HttpServerDemo.kt[tags=user_guide]
----
--
====

[[migration]]
[TIP]
.Migration Note for Resource Cleanup
====
======
The framework automatically closes resources stored in the `ExtensionContext.Store` that
implement `AutoCloseable`. In versions prior to 5.13, only resources implementing
`Store.CloseableResource` were automatically closed.
Expand All @@ -79,6 +127,11 @@ If you're developing an extension that needs to support both JUnit Jupiter 5.13+
earlier versions and your extension stores resources that need to be cleaned up, you
should implement both interfaces:

[tabs]
====
Java::
+
--
[source,java,indent=0]
----
public class MyResource implements Store.CloseableResource, AutoCloseable {
Expand All @@ -88,7 +141,22 @@ public class MyResource implements Store.CloseableResource, AutoCloseable {
}
}
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
class MyResource : Store.CloseableResource, AutoCloseable {
override fun close() {
// Resource cleanup code
}
}
----
--
====

This ensures that your resource will be properly closed regardless of which JUnit Jupiter
version is being used.
====
======
Original file line number Diff line number Diff line change
Expand Up @@ -60,38 +60,102 @@ registered for a test, a `ParameterResolutionException` will be thrown, with a
message to indicate that competing resolvers have been discovered. See the following
example:

[source,java,indent=0]
.Conflicting parameter resolution due to multiple resolvers claiming support for integers
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/extensions/ParameterResolverConflictDemo.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/extensions/ParameterResolverConflictDemo.kt[tags=user_guide]
----
--
====

If the conflicting `ParameterResolver` implementations are applied to different test
methods as shown in the following example, no conflict occurs.

[source,java,indent=0]
.Fine-grained registration to avoid conflict
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/extensions/ParameterResolverNoConflictDemo.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/extensions/ParameterResolverNoConflictDemo.kt[tags=user_guide]
----
--
====

If the conflicting `ParameterResolver` implementations need to be applied to the same test
method, you can implement a custom type or custom annotation as illustrated by
`{CustomTypeParameterResolver}` and `{CustomAnnotationParameterResolver}`, respectively.

[source,java,indent=0]
.Custom type to resolve duplicate types
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/extensions/ParameterResolverCustomTypeDemo.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/extensions/ParameterResolverCustomTypeDemo.kt[tags=user_guide]
----
--
====

A custom annotation makes the duplicate type distinguishable from its counterpart:

[source,java,indent=0]
.Custom annotation to resolve duplicate types
[tabs]
====
Java::
+
--
[source,java,indent=0]
----
include::example$java/example/extensions/ParameterResolverCustomAnnotationDemo.java[tags=user_guide]
----
--

Kotlin::
+
--
[source,kotlin,indent=0]
----
include::example$kotlin/example/kotlin/extensions/ParameterResolverCustomAnnotationDemo.kt[tags=user_guide]
----
--
====

JUnit includes some built-in parameter resolvers that can cause conflicts if a resolver
attempts to claim their supported types. For example, `{TestInfo}` provides metadata about
Expand Down
Loading
Loading