Spring Boot 2 with JUnit 5 Testing Example

In this article, we will quickly discuss how to set up and integrate JUnit 5 with Spring Boot 2 with a simple example.
Note that JUnit 5 and Spring Boot 2 requires minimum JDK 8 or later version so make sure that you have JDK 8 or later installed. 
Let's create a simple maven based Spring boot 2 project to demonstrates usages of JUnit 5 tests.
If you are new to JUnit 5 then I suggest you learn end to end JUnit 5 with examples on a one of the top tutorial - JUnit 5 Tutorial

1. What we'll build?

We will develop a simple Spring Boot application and we will do Rest API testing using JUnit 5.

2. Tools and Technologies Used

  • Spring Boot - 2.0.5.RELEASE
  • JDK - 1.8 or later
  • Spring Framework - 5.0.8 RELEASE
  • Maven - 3.2+
  • JUnit 5 
  • IDE - Eclipse or Spring Tool Suite (STS)

3. Creating and Importing a Project

There are many ways to create a Spring Boot application. The simplest way is to use Spring Initializr at http://start.spring.io/, which is an online Spring Boot application generator. 
Spring Boot 2 with JUnit 5 Testing Example
Create project packaging structure as per below diagram:
Spring Boot 2 with JUnit 5 Testing Example
The next step is very important.

4. Update pom.xml File

The spring-boot-starter-parent inherits properties from a spring-boot-dependencies project which is a parent of spring-boot-starter-parent
 <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.0.5.RELEASE</version>
     <relativePath /> <!-- lookup parent from repository -->
 </parent>
By default, spring-boot-starter-parent has JUnit 4.12 version as follows.
 <junit.version>4.12</junit.version>
Now, we need to use JUnit 5 so let's exclude JUnit 4.12 from spring-boot-starter-test dependency.
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Let's add JUnit 5 dependencies:
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
</dependency>
No need to specify the versions above dependencies because the versions are already defined in spring-boot-dependencies dependency(this is a parent of spring-boot-starter-parent starter) such as:
<junit-jupiter.version>5.1.1</junit-jupiter.version>
<junit-platform.version>1.1.0</junit-platform.version>
Let's put together and complete pom.xml looks as:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>net.guides.springboot2</groupId>
 <artifactId>springboot2-junit5-example</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>springboot2-junit5-example</name>
 <description>Demo project for Spring Boot</description>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.5.RELEASE</version>
  <relativePath /> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
   <exclusions>
    <exclusion>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
    </exclusion>
   </exclusions>
  </dependency>
  <dependency>
   <groupId>org.junit.jupiter</groupId>
   <artifactId>junit-jupiter-api</artifactId>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.junit.jupiter</groupId>
   <artifactId>junit-jupiter-engine</artifactId>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
   </plugin>
  </plugins>
 </build>
</project>

5. Create Spring Rest Controller - MessageController.java

Let's create a simple Spring rest controller to do JUnit test.
package net.guides.springboot2.springboot2junit5example.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MessageController {

 @GetMapping("/hello")
 public String hello() {
  return "Hello World";
 }

}

6. Test MessageController Using JUnit 5

package net.guides.springboot2.springboot2junit5example;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class Springboot2Junit5ExampleApplicationTests {

 @Autowired
 private TestRestTemplate restTemplate;

 @Test
 @DisplayName("test Message REST API ")
 void testMessage() {
  String message = this.restTemplate.getForObject("/hello", String.class);
  assertEquals("Hello World", message);
 }

}
Note that the test class is annotated with the @ExtendWith annotation where its value is the SpringExtension.class:
@ExtendWith(SpringExtension.class)
The SpringExtension class integrates the Spring TestContext Framework into JUnit 5’s Jupiter programming model and the @ExtendWith annotation allows us to register the extension for the annotated test class.
In the above example, we have used few JUnit 5 annotations like @Test, @DisplayName.

7. Running JUnit 5 and Spring Boot Tests

This is a maven based project so execute tests in IDE by right click project -> run as maven test will produce the following output:
Spring Boot 2 with JUnit 5 Testing Example

Or If your IDE and it supports JUnit 5 then follow below steps to execute JUnit 5 tests.
  1. Open Springboot2Junit5ExampleApplicationTests.java file
  2. Right-click in Springboot2Junit5ExampleApplicationTests.java file
  3. Run as JUnit Test
Spring Boot 2 with JUnit 5 Testing Example

8. Source code on GitHub

The source code of this article available on my GitHub repository on springboot2-junit5-example


Comments