Spring Boot - Unit Test Cases



Unit Testing is a one of the testing done by the developers to make sure individual unit or component functionalities are working fine.

In this tutorial, we are going to see how to write a unit test case by using Mockito and Web Controller.

Mockito

For injecting Mockito Mocks into Spring Beans, we need to add the Mockito-core dependency in our build configuration file.

In this chapter, we are going to see how to use Mockito in Spring Boot application.

First, download the Spring Boot project from Spring Initializer page www.start.spring.io.

Creating Mockito Project

Maven users can add the following dependency in your pom.xml file.

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-core</artifactId>
</dependency>

Gradle users can add the following dependency in the build.gradle file.

compile group: 'org.mockito', name: 'mockito-core', version: '5.13.0'
testCompile('org.springframework.boot:spring-boot-starter-test')

The code to write a Service class which contains a method that returns the String value is given here.

ProductService.java

package com.tutorialspoint.mockito;

import org.springframework.stereotype.Service;

@Service
public class ProductService {
   public String getProductName() {
      return "Honey";
   } 
}

Now, inject the ProductService class into another Service class file as shown.

OrderService.java

package com.tutorialspoint.mockito;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
   @Autowired
   ProductService productService;

   public OrderService(ProductService productService) {
      this.productService = productService;
   }
   public String getProductName() {
      return productService.getProductName();
   }
}

The main Spring Boot application class file is given below −

MockitoApplication.java

package com.tutorialspoint.mockitodemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

Then, configure the Application context for the tests. The @Profile("test") annotation is used to configure the class when the Test cases are running.

ProductServiceTestConfiguration.java

package com.tutorialspoint.mockito;

import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;

@Profile("test")
@Configuration
public class ProductServiceTestConfiguration {
   @Bean
   @Primary
   ProductService productService() {
      return Mockito.mock(ProductService.class);
   }
}

Now, you can write a Unit Test case for Order Service under the src/test/java package.

MockitoApplicationTests.java

package com.tutorialspoint.mockito;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

@SpringBootTest
@ActiveProfiles("test")
@ExtendWith(MockitoExtension.class)
public class MockitoApplicationTests {
   @Autowired
   private OrderService orderService;
   
   @Autowired
   private ProductService productService;

   @Test
   public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
      Mockito.when(productService.getProductName()).thenReturn("Mock Product Name");
      String testName = orderService.getProductName();
      assertEquals("Mock Product Name", testName);
   }
}

The complete code for build configuration file is given below.

Maven pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>3.3.4</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.tutorialspoint</groupId>
   <artifactId>mockito</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>mockito</name>
   <description>Demo project for Spring Boot</description>
   <url/>
   <licenses>
      <license/>
   </licenses>
   <developers>
      <developer/>
   </developers>
   <scm>
      <connection/>
      <developerConnection/>
      <tag/>
      <url/>
   </scm>
   <properties>
      <java.version>21</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-core</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

Gradle build.gradle

buildscript {
   ext {
      springBootVersion = '3.3.4'
   }
   repositories {
      mavenCentral()
   }
   dependencies {
      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
   }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

group = 'com.tutorialspoint'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 21

repositories {
   mavenCentral()
}
dependencies {
   compile('org.springframework.boot:spring-boot-starter')
   compile group: 'org.mockito', name: 'mockito-core', version: '5.13.0'
   testCompile('org.springframework.boot:spring-boot-starter-test')
}   

Compilation and Execution

You can create an executable JAR file, and run the Spring Boot application by using the following Maven or Gradle1 commands.

For Maven, you can use the command as shown −

mvn clean install 

You can see the test results in console window.

[INFO] Scanning for projects...
[INFO] 
[INFO] [1m------------------------------------------[m
[INFO] [1mBuilding mockito 0.0.1-SNAPSHOT[m
[INFO]   from pom.xml
[INFO] [1m--------------------------------[ jar ]---------------------------------[m
[INFO] 
[INFO] [1m--- [0;32mresources:3.3.1:resources[m [1m(default-resources)[m @ [36mmockito[0;1m ---[m
[INFO] Copying 1 resource from src\main\resources to target\classes
[INFO] Copying 0 resource from src\main\resources to target\classes
[INFO] 
[INFO] [1m--- [0;32mcompiler:3.13.0:compile[m [1m(default-compile)[m @ [36mmockito[0;1m ---[m
[INFO] Nothing to compile - all classes are up to date.
[INFO] 
[INFO] [1m--- [0;32mresources:3.3.1:testResources[m [1m(default-testResources)[m @ [36mmockito[0;1m ---[m
[INFO] skip non existing resourceDirectory E:\Dev\mockito\src\test\resources
[INFO] 
[INFO] [1m--- [0;32mcompiler:3.13.0:testCompile[m [1m(default-testCompile)[m @ [36mmockito[0;1m ---[m
[INFO] Nothing to compile - all classes are up to date.
[INFO] 
[INFO] [1m--- [0;32msurefire:3.2.5:test[m [1m(default-test)[m @ [36mmockito[0;1m ---[m
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.tutorialspoint.mockito.[1mMockitoApplicationTests[m
12:01:28.057 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.tutorialspoint.mockito.MockitoApplicationTests]: MockitoApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
12:01:28.190 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.tutorialspoint.mockito.MockitoApplication for test class com.tutorialspoint.mockito.MockitoApplicationTests

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.4)

2024-09-25T12:01:28.643+05:30  INFO 11396 --- [mockito] [           main] c.t.mockito.MockitoApplicationTests      : Starting MockitoApplicationTests using Java 21.0.3 with PID 11396 (started by Tutorialspoint in E:\Dev\mockito)
2024-09-25T12:01:28.645+05:30  INFO 11396 --- [mockito] [           main] c.t.mockito.MockitoApplicationTests      : The following 1 profile is active: "test"
WARNING: A Java agent has been loaded dynamically (C:\Users\Tutorialspoint\.m2\repository\net\bytebuddy\byte-buddy-agent\1.14.19\byte-buddy-agent-1.14.19.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
2024-09-25T12:01:30.331+05:30  INFO 11396 --- [mockito] [           main] c.t.mockito.MockitoApplicationTests      : Started MockitoApplicationTests in 1.984 seconds (process running for 3.181)
[INFO] [1;32mTests run: [0;1;32m1[m, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.640 s -- in com.tutorialspoint.mockito.[1mMockitoApplicationTests[m
[INFO] 
[INFO] Results:
[INFO] 
[INFO] [1;32mTests run: 1, Failures: 0, Errors: 0, Skipped: 0[m
[INFO] 
[INFO] 
[INFO] [1m--- [0;32mjar:3.4.2:jar[m [1m(default-jar)[m @ [36mmockito[0;1m ---[m
[INFO] Building jar: E:\Dev\mockito\target\mockito-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] [1m--- [0;32mspring-boot:3.3.4:repackage[m [1m(repackage)[m @ [36mmockito[0;1m ---[m
[INFO] Replacing main artifact E:\Dev\mockito\target\mockito-0.0.1-SNAPSHOT.jar with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] The original artifact has been renamed to E:\Dev\mockito\target\mockito-0.0.1-SNAPSHOT.jar.original
[INFO] 
[INFO] [1m--- [0;32minstall:3.1.3:install[m [1m(default-install)[m @ [36mmockito[0;1m ---[m
[INFO] Installing E:\Dev\mockito\pom.xml to C:\Users\Tutorialspoint\.m2\repository\com\tutorialspoint\mockito\0.0.1-SNAPSHOT\mockito-0.0.1-SNAPSHOT.pom
[INFO] Installing E:\Dev\mockito\target\mockito-0.0.1-SNAPSHOT.jar to C:\Users\Tutorialspoint\.m2\repository\com\tutorialspoint\mockito\0.0.1-SNAPSHOT\mockito-0.0.1-SNAPSHOT.jar
[INFO] [1m------------------------------------------------------------------------[m
[INFO] [1;32mBUILD SUCCESS[m
[INFO] [1m------------------------------------------------------------------------[m
[INFO] Total time:  6.370 s
[INFO] Finished at: 2024-09-25T12:01:31+05:30
[INFO] [1m------------------------------------------------------------------------[m

For Gradle, you can use the command as shown −

gradle clean build 
Advertisements