Generic Top

Finally announcing my next course. The intro price of the upcoming “Learn Spring” course will permanently increase by $50 on Friday:


1. Overview

JUnit is one of the most popular unit testing frameworks for Java, so it is a big deal in the developer community when new major versions come out. An alpha version of JUnit 5 was released in early February, and it contains a number of exciting innovations.

This article will explore the new features of this release, and the main differences with previous versions.

2. Dependencies and Setup

Installing JUnit 5 is pretty straightforward. Just add the following dependency to your pom.xml:


However, at the moment no IDEs support JUnit 5 yet, so you will also have to specify a build script:


It is important to note that this version requires Java 8 to work.

When creating a test, make sure you import org.junit.jupiter.api.Test, not org.junit.Test. Also, the test methods no longer need to be public; package local will do.

3. What’s New

JUnit 5 tries to take full advantage of the new features from Java 8, especially lambda expressions.

3.1. Assertions

Assertions have been moved to org.junit.jupiter.api.Assertions and have been improved significantly. As mentioned earlier, you can now use lambdas in assertions:

void lambdaExpressions() {
    assertTrue(Stream.of(1, 2, 3)
      .mapToInt(i -> i)
      .sum() > 5, () -> "Sum should be greater than 5");

Although the example above is trivial, one advantage of using the lambda expression for the assertion message is that it is lazily evaluated, which can save time and resources if the message construction is expensive.

It is also now possible to group assertions with assertAll() which will report any failed assertions within the group with a MultipleFailuresError:

 void groupAssertions() {
     int[] numbers = {0, 1, 2, 3, 4};
         () -> assertEquals(numbers[0], 1),
         () -> assertEquals(numbers[3], 3),
         () -> assertEquals(numbers[4], 1)

This means it is now safer to make more complex assertions, as you will be able to pinpoint the exact location of any failure.

3.2. Assumptions

Assumptions are used to run tests only if certain conditions are met. This is typically used for external conditions that are required for the test to run properly, but which are not directly related to whatever is being tested.

You can declare an assumption with assumeTrue(), assumeFalse(), and assumingThat().

void trueAssumption() {
    assumeTrue(5 > 1);
    assertEquals(5 + 2, 7);

void falseAssumption() {
    assumeFalse(5 < 1);
    assertEquals(5 + 2, 7);

void assumptionThat() {
    String someString = "Just a string";
        someString.equals("Just a string"),
        () -> assertEquals(2 + 2, 4)

If an assumption fails, a TestAbortedException is thrown and the test is simply skipped.

Assumptions also understand lambda expressions.

3.3. Exceptions

JUnit 5 improves support for exceptions. An assertThrows() method has been added that verifies that an expression throws an expression of a given type:

void shouldThrowException() {
    Throwable exception = assertThrows(UnsupportedOperationException.class, () -> {
      throw new UnsupportedOperationException("Not supported");
    assertEquals(exception.getMessage(), "Not supported");

As the example demonstrates, JUnit 5 offers more control over the thrown exceptions than JUnit 4 used to. The most obvious implication is that it is now possible to easily get any information we might need about the exception, as we did in our example by inspecting the exception message.

3.4. Nested Tests

Nested tests have been added to allow developers to express complex relationships between different groups of tests. The syntax is quite straightforward – all you have to do is annotate an inner class with @Nested.

The JUnit documentation offers an elaborate example, which illustrates one of the possible uses.

3.5. Disabling Tests

Tests can now be disabled with the @Disabled annotation.

void disabledTest() {

This test will not be run. The @Disabled annotation can be applied to either a test case or a test method and is equivalent to @Ignore from JUnit 4.

3.6. Tagging

Tags are the replacement for Categories from JUnit 4. Tags can be applied with the @Tag annotation. These allow developers to group and filter tests.

@Tag("Test case")
public class TaggedTest {

    void testMethod() {
        assertEquals(2+2, 4);

4. Conclusion

The write-up was a quick overview of the changes that are coming with JUnit 5.

It is important to note that at the moment of writing only the Alpha build was available, so some things might still change before release.

The examples used in this article can be found in the linked GitHub project.

Generic bottom

Finally announcing my next course. The intro price of the upcoming “Learn Spring” course will permanently increase by $50 on Friday:


newest oldest most voted
Notify of
Walker Berry
Walker Berry

Love the progress they are making on this (and glad they changed the name)! I would use all these things without any hesitation. I hope it’s fast and has good ide/maven/gradle integrations, but given its jUnit– I bet it will.

It’s a pretty good time to be a TDD enthusiast in Java, esp if you work in Spring (releasing testing enhancements in next Spring Boot major iteration currently in milestone).

Thanks for the examples and explanations!

Eugen Paraschiv

Yeah, it’s been a long time coming – I’m pretty excited to start using it as well.
I’m glad you’re enjoying the material. Cheers,