Skip to content

OLD Prototype Test Extensions

Marc Philipp edited this page Feb 7, 2017 · 1 revision

Writing Test Extensions for JUnit 5

Table of Contents

Overview

In contrast to the competing Runner, @Rule, and @ClassRule extension points in JUnit 4, the JUnit 5 extension model consists of a single, coherent concept: the TestExtension API. Note, however, that TestExtension itself is just a marker interface.

Registering Extensions

Developers can register one or more extensions by annotating a test class or test method with @ExtendWith(...), supplying class references for the extensions to register. For example, to register a custom MockitoExtension, you would annotate your test class as follows.

@ExtendWith(MockitoExtension.class)
class MockTests {
  // ...
}

Multiple extensions can be registered together like this:

@ExtendWith({ FooExtension.class, BarExtension.class })
class MyTestsV1 {
  // ...
}

As an alternative, multiple extensions can be registered separately like this:

@ExtendWith(FooExtension.class)
@ExtendWith(BarExtension.class)
class MyTestsV2 {
  // ...
}

The execution of tests in both MyTestsV1 and MyTestsV2 will be extended by the FooExtension and BarExtension, in exactly that order.

Registered extensions are inherited within test class hierarchies.

Conditional Test Execution

Condition defines the TestExtension API for programmatic, conditional test execution.

A Condition is evaluated to determine if a given test (e.g., class or method) should be executed based on the supplied TestExecutionContext. When evaluated at the class level, a Condition applies to all test methods within that class.

See the source code of DisabledCondition and @Disabled for a concrete example.

Test Instance Post-processing

InstancePostProcessor defines the API for TestExtensions that wish to post process test instances.

Common use cases include injecting dependencies into the test instance, invoking custom initialization methods on the test instance, etc.

For concrete examples, consult the source code for MockitoExtension and SpringExtension.

Parameter Resolution

MethodParameterResolver is a TestExtension strategy for dynamically resolving method parameters at runtime.

If a @Test, @BeforeEach, or @AfterEach method accepts a parameter, the parameter must be resolved at runtime by a MethodParameterResolver. A MethodParameterResolver can either be built-in (see TestNameParameterResolver) or registered by the user via @ExtendWith. Generally speaking, parameters may be resolved by type or by annotation. For concrete examples, consult the source code for CustomTypeParameterResolver and CustomAnnotationParameterResolver, respectively.

Test Lifecycle Callbacks

The following interfaces define the APIs for extending tests at various points in the test execution lifecycle. Consult the Javadoc for each of these in the org.junit.gen5.api.extension package.

  • BeforeEachCallbacks
  • AfterEachCallbacks
  • BeforeAllCallbacks
  • AfterAllCallbacks

Note that extension developers may choose to implement any number of these interfaces within a single extension. Consult the source code of the SpringExtension for a concrete example.

Additional Planned Extension Points

The JUnit Lambda team is planning several additional extension points, including but not limited to the following.

  • Dynamic test registration -- for example, for computing parameterized tests at runtime