

By far the most popular java library
Last major release in 2006

JUnit 4 Limitations
- Difficult to evolve
- One Jar used by:
- Developers
- Build tools + IDEs (maven/gradle +intellij/eclipse)
- One Jar used by:
- No lambda support
- Difficult to extend
JUnit 5 Origins
- Started by a group of test enthusiasts + JUnit 4 maintainers
- Originally called JUnit Lambda
- Crowdfunded project in 2015
- €53,937 raised by 474 backers
- Completely rewritten (but backward compatible)
- Released October 2017

JUnit 5 in a nutshell
- New modular architecture
- Forward and backward compatible
- New Extension model
- Rules and Runners replaced with Extensions
- Dependency Injection support
- New features
- Lambda support
- Nested tests
- Dynamic tests
- Classes & Tests can be package protected
- Some renaming
New Modular Architecture!
New Modular Architecture
- Separating concerns
- An API for writing tests
- An engine to discover and run tests
- An engine to discover and run a specific type of test (JUnit 4, JUnit5, Cucumber...)
- A platform to run this engine and report results
- A engine API in between them
Three projects evolved
-
- JUnit Jupiter
- New Test API and Engine Implementation
- JUnit Vintage
- Engine Implementation for JUnit 4
- JUnit Platform
- Engine API and Platform API for build tools/IDEs
- JUnit Jupiter

New Extension Model!
Rules and Runners replaced with Extensions
JUnit 4 Extension Model
@RunWith(Parameterized.class)
@RunWith(Cucumber.class)
@RunWith(PowerMockRunner.class)- Test Runners
- The only way to extend JUnit until 4.7
- Very Powerful
- Heavyweight
- Could only have one runner on a class
JUnit 4 Extension Model
@Rule
public ExpectedException exception = ExpectedException.none();
@ClassRule
public static final KafkaJunitRule KAFKA_RULE = new KafkaJunitRule();- Test Rules in JUnit 4.7
- Big improvement
- Generally limited to running some code before and after a test
JUnit 5 Extensions
@ExtendWith(KafkaJunitExtension.class, MockitoExtension.class)
class KafkaIntegrationTest {
Extend your test class with the @ExtendWith annotation
JUnit 5 Extensions
public class KafkaJunitExtension implements BeforeAllCallback, AfterEachCallback,
BeforeEachCallback, AfterAllCallback,
ParameterResolver- Extensions can Implement as many extension points as needed
Extension Points
BeforeAllCallback
BeforeEachCallback
BeforeTestExecutionCallback
AfterTestExecutionCallback
AfterEachCallback
AfterAllCallback
Lifecycle Extension points
TestExecutionExceptionHandler
ExecutionCondition
ParameterResolver
TestInstancePostProcessor
Dependency Injection Extension points
Parameter Injection
Extensions can inject parameters into:
- Constructors
- SetUp/TearDown methods
- Test methods
@Test
@DisplayName("messages should be transformed and republished to Kafka")
void transform_and_republish_to_kafka(EphemeralKafkaBroker broker) {
broker.getKafkaPort()
...
}New Features!
Lambda support
Assertions.assertAll(() -> assertThat(msg).isNotNull(),
() -> assertThat(msg.key()).isEqualTo("keyA"),
() -> assertThat(msg.value()).isEqualTo("valueA"))assertThrows(IllegalArgumentException.class, () -> viewMetadata.setTopN(-1))assertFalse(testConditionIsTrue(), () -> "Really " + "expensive " + "message" + ".");Test Interfaces
public interface ComparableContract<T extends Comparable<T>> extends Testable<T> {
T createSmallerValue();
@Test
default void returnsZeroWhenComparedToItself() {
T value = createValue();
assertEquals(0, value.compareTo(value));
}
@Test
default void returnsPositiveNumberComparedToSmallerValue() {
T value = createValue();
T smallerValue = createSmallerValue();
assertTrue(value.compareTo(smallerValue) > 0);
}
@Test
default void returnsNegativeNumberComparedToSmallerValue() {
T value = createValue();
T smallerValue = createSmallerValue();
assertTrue(smallerValue.compareTo(value) < 0);
}
}Nested Test Classes
Demo
Migration
- Started with our smallest repository
- What dependencies do I need?
- No longer just one jar
- What to do about Rules and Runners?
- Backward compatible but ideally convert to extensions
Questions?
JUnit 5
By Tom Hanley
JUnit 5
- 86