Spring Boot - 单元测试用例



单元测试是由开发人员进行的一种测试,以确保各个单元或组件的功能正常工作。

在本教程中,我们将学习如何使用 Mockito 和 Web Controller 编写单元测试用例。

Mockito

为了将 Mockito 模拟对象注入 Spring Bean,我们需要在构建配置文件中添加 Mockito-core 依赖项。

本章将介绍如何在 Spring Boot 应用程序中使用 Mockito。

首先,从 Spring Initializer 页面下载 Spring Boot 项目 www.start.spring.io

Creating Mockito Project

Maven 用户可以在 pom.xml 文件中添加以下依赖项。

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

Gradle 用户可以在 build.gradle 文件中添加以下依赖项。

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

这里给出了一个包含返回字符串值的 Service 类方法的代码。

ProductService.java

package com.tutorialspoint.mockito; import org.springframework.stereotype.Service; @Service public class ProductService { public String getProductName() { return "Honey"; } }

现在,将 ProductService 类注入另一个 Service 类文件,如下所示。

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(); } }

主要的 Spring Boot 应用程序类文件如下所示:

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); } }

然后,为测试配置 Application 上下文。@Profile("test") 注解用于在运行测试用例时配置类。

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); } }

现在,您可以为 Order Service 编写单元测试用例,位于 src/test/java 包下。

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); } }

完整的构建配置文件代码如下所示。

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')
}   

编译和执行

您可以创建一个可执行的 JAR 文件,并使用以下 Maven 或 Gradle 命令运行 Spring Boot 应用程序。

对于 Maven,您可以使用如下所示的命令:

mvn clean install 

您可以在控制台窗口中看到测试结果。

[INFO] Scanning for projects...
[INFO] 
[INFO] [1m---------------------< [0;36mcom.tutorialspoint:mockito[0;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

对于 Gradle,您可以使用如下所示的命令:

gradle clean build 
广告