How To Write Junit Test For Spring Boot Main Class

Introduction

Here I am going to show you how to write Junit test for Spring Boot main class. A class having main method in Spring boot application is called main class and the purpose of this class is to deploy the application into embedded Tomcat server without configuring deployment descriptor or generating war file for the application. This way you as a developer need to focus only on writing the business logic for the application.

Junit tests are written to check the coding standards and code quality so that your application’s functionalities remain bug free in production environment.

The quality will be 100% if the code coverage through Junit test cases are covered 100%. It becomes sometime difficult to maintain code coverage as 100%, so generally 80-85% is considered as a good coverage for deploying the applications into production environment.

I think for most of the Spring boot applications, the main class is left without junit coverage and in case you need to create a junit for main class for making the tool happy then you can write it.

Let’s say a scenario where your application is actually front-end application, but is built with Spring boot framework and the application has only main class. In such case while your Jenkins pipeline is built, it fails due to Sonar issue, because you must write junit test for the main class to meet the minimum 50% code coverage. So, here is the example which will help you to write the junit class for the Spring boot main class.

If your main class is simple, I mean to say if application’s main class does not extend a class or implement an interface then your junit will be very simple. In case your main class extends, for example, SpringBootServletInitializer class then you may also want to write junit test for testing the part of the SpringBootServletInitializer.

Prerequisites

Java 1.8+, Maven 3.8.2+/Gradle 5.6.1+, Spring Boot 2.3.2 – 2.7.0, Junit 4.13.2, Mockito 4.5.1

Project Setup

I am creating here maven based project and the following pom.xml file can be used for this project:

<?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>com.roytuts</groupId>
	<artifactId>springboot-main-springbootservletinitializer-junit</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.0</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Spring Boot App

I am creating a simple Spring boot app which has just a main class. I will also show how to write junit for main class when it extends SpringBootServletInitializer class.

Let’s say you can have either the main class as follows:

@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

Or you can have the main class as follows:

@SpringBootApplication

public class App extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
		return springApplicationBuilder.sources(App.class);
	}

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

Or you can have the main class written in different way, but I will show you junit tests for the above two scenario.

Junit for Spring Boot Main Class

Now I am going to write junit test class for the above two scenarios. When you have only main method and the main class does not extend SpringBootServletInitializer class, the junit can be written for the main class as follows:

public class AppTest {

	@Test
	public void testMain() {
		App.main(new String[] {});
		assertTrue(true);
	}
	
}

When the main class extends SpringBootServletInitializer class and overrides the configure() method from parent class, then you can write junit as follows:

@RunWith(MockitoJUnitRunner.class)
public class AppTest {

	@Mock
	private SpringApplicationBuilder springApplicationBuilder;

	@Test
	public void testConfigure() {
		App app = new App();

		Mockito.when(springApplicationBuilder.sources(App.class)).thenReturn(springApplicationBuilder);

		SpringApplicationBuilder result = app.configure(springApplicationBuilder);

		Mockito.verify(springApplicationBuilder).sources(App.class);

		assertEquals(springApplicationBuilder, result);
	}
	
}

Notice the @RunWith annotation is required for creating mock instance (using @Mock annotation) for the SpringApplicationBuilder.

The above junit tests cover 100% coverage for your main class code.

Hope you have solved the code coverage issue/blocker issue in SonarQube.

Source Code

Download

Leave a Reply

Your email address will not be published.