千家信息网

SpringBoot单元测试如何实现

发表于:2025-11-14 作者:千家信息网编辑
千家信息网最后更新 2025年11月14日,这篇文章将为大家详细讲解有关SpringBoot单元测试如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。demo(SpringBoot 项目)被测试类:imp
千家信息网最后更新 2025年11月14日SpringBoot单元测试如何实现

这篇文章将为大家详细讲解有关SpringBoot单元测试如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

demo(SpringBoot 项目)

被测试类:

import org.springframework.stereotype.Service;@Servicepublic class TestService {    public String sayHi() {        return "hi";    }    public int divide(int a, int b) {        return a / b;    }}

测试代码:

import static org.junit.Assert.*;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)@SpringBootTestpublic class TestServiceTest {    @Autowired    TestService testService;    @Test    public void testSayHi() {        TestService testService = new TestService();        String result = testService.sayHi();        assertEquals("hi", result);    }    @Test    public void testDivide() {        TestService testService = new TestService();        int result = testService.divide(3, 6);        assertTrue(result > -1);    }}

pom.xml 配置文件

![cobertura](C:\Users\jiaflu\Desktop\cobertura.PNG)    4.0.0            org.springframework.boot        spring-boot-starter-parent        2.1.5.RELEASE                 com.jiaflu    learn_springoot    0.0.1-SNAPSHOT    learn_springoot    Demo project for Spring Boot            1.8        2.9.8                            org.springframework.boot            spring-boot-starter                            org.springframework.boot            spring-boot-starter-test            test                            org.springframework.boot            spring-boot-starter-web                                                    org.springframework.boot                spring-boot-maven-plugin                                        org.apache.maven.plugins                maven-compiler-plugin                                    1.8                    1.8                                                        org.apache.maven.plugins                maven-surefire-plugin                2.5                                        org.codehaus.mojo                cobertura-maven-plugin                2.5.2                                    UTF-8                                            html                        xml                                                            

运行mvn cobertura:cobertura 查看截图:

覆盖率测试报告生成(cobertura)

cobertura 原理

cobertura执行过程大致如下:

  • 使用instrument修改我们编译后的class文件,位于 target\generated-classes。

  • 执行测试,测试数据输出到xxx.ser中,位于 target\cobertura\cobertura.ser。

  • 使用report生成覆盖率报告。

1.instrument

instrument:cobertura使用instrument修改我们编译后的class文件,在代码里面加入cobertura的统计代码。并生成一个.ser文件(用于覆盖率数据的输出)。

使用 instrument 执行的过程中,CoberturaInstrumenter 会首先调用分析监听器分析给定的编译好的.class,获得touchPoint(可以认为对应于源代码中的待覆盖行)以及需要的其他信息。然后调用注入监听器将信息注入到新的.class中,保存到 \target\generated-classes 目录下。

示例:

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.cisco.webex.cmse.soa.soaservice.service;import net.sourceforge.cobertura.coveragedata.HasBeenInstrumented;import net.sourceforge.cobertura.coveragedata.TouchCollector;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.PropertySource;import org.springframework.stereotype.Service;@PropertySource({"classpath:application.properties"})@Servicepublic class PropertyService implements HasBeenInstrumented {    private static final Logger logger;    @Value("${cdp.instance.url}")    private String cdpInstanUrl;    @Value("${soa.instance.url}")    private String soaInstanceUrl;    @Value("${github.api.token}")    public String gitApiToken;    @Value("${github.instance.url}")    private String githubInstance;    @Value("${github.repo.template.owner}")    private String tplRepoOwner;    @Value("${github.repo.consul.owner}")    private String consulRepoOwner;    @Value("${slm.listen.queue.name}")    private String slmListenQueue;    public PropertyService() {        boolean var1 = false;        int __cobertura__branch__number__ = true;        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 12);        super();    }    public String getCdpInstanUrl() {        boolean var1 = false;        int __cobertura__branch__number__ = true;        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 33);        return this.cdpInstanUrl;    }    ...    public void setSlmListenQueue(String ()V) {        boolean var2 = false;        int __cobertura__branch__number__ = true;        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 85);        this.slmListenQueue = slmListenQueue;        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 86);    }    static {        boolean var0 = false;        boolean var1 = true;        TouchCollector.touch("com.cisco.webex.cmse.soa.soaservice.service.PropertyService", 13);        logger = LoggerFactory.getLogger(PropertyService.class);    }}

2.执行测试

在执行测试用例时,引用 cobertura 修改过的.class,测试信息写入到cobertura.ser档案文件。

3.生成报告

从cobertura.ser获取覆盖率数据,然后结合src中提供的源代码,生成最终的覆盖率报告,放到了target\site\cobertura路径下。若配置了生成 html 格式的报告,可以通过 index.html 查看覆盖率测试报告。

SpringBoot pom.xml 配置

添加如下依赖:

                   org.springframework.boot                spring-boot-maven-plugin                                        org.apache.maven.plugins                maven-compiler-plugin                                    1.8                    1.8                                                        org.apache.maven.plugins                maven-surefire-plugin                2.5                                                        -noverify                                                        org.codehaus.mojo                cobertura-maven-plugin                2.5.2                                                            xml                        html                                                

采坑:

在使用 mvn cobertura:cobertura 命令生成测试覆盖率报告时,出现了如下问题(截取部分,报错原因如下):

Reason:

Expected stackmap frame at this location.

Bytecode:

0x0000000: 2ab4 001b 2bb9 002e 0200 c600 2f2a b400

0x0000010: 1b2b b900 2e02 00c0 0030 b600 34c6 001c

解决方法:

本人使用的是 jdk1.8,添加 jvm 参数 -noverify,可以在 pom 文件中添加配置,配置见上述 pom.xml

网上查资料 jdk1.7 添加 jvm 参数 -XX:-UseSplitVerifier,(1.8没有 -XX:-UseSplitVerifier 这参数)

命令介绍

  • cobertura:check

根据最新的源码标记(生成的class文件)校验测试用例的覆盖率,如果没有达到要求,则执行失败.

  • cobertura:check-integration-test

这个命令和cobertura:check功能是一样的,区别是二者绑定的maven生命周期不一样.cobertura:check绑定了test, cobertura:check-integration-test绑定了verify.再说的明白些,maven生命周期中有一个是test跑得单元测试,还有一个是integration-test跑的集成测试.而verify前就是integration-test.即cobertura:check-integration-test比cobertura:check涵盖的测试用例更多.

  • cobertura:clean

这个好理解,就是清理掉目录/target/cobertura/中得文件.目前发现里面就一个文件cobertura.ser.

  • cobertura:cobertura

这个插件的关键命令.标记被编译的文件,运行单元测试,生成测试报告.

  • cobertura:cobertura-integration-test

和cobertura:cobertura做了一样的事情,区别是包含了集成测试用例.

  • cobertura:dump-datafile

在命令行输出覆盖率数据.数据依据是生成的class文件.这个命令我没搞懂他的意义何在.在后面一个有趣的实验我们会用这个命令来更好的理解cobertura-maven-plugin.

  • cobertura:help

  • cobertura:instrument

标记被编译的class文件.执行这个命令会在目录/target/generated-classes/cobertura下生成一套class文件.

maven-surefire-plugin 使用说明

Maven本身并不是一个单元测试框架,它只是在构建执行到特定生命周期阶段的时候,通过插件来执行JUnit或者TestNG的测试用例。这个插件就是maven-surefire-plugin,也可以称为测试运行器(Test Runner),它能兼容JUnit 3、JUnit 4以及TestNG。

在默认情况下,maven-surefire-plugin的test目标会自动执行测试源码路径(默认为src/test/java/)下所有符合一组命名模式的测试类。这组模式为:

  • */Test.java:任何子目录下所有命名以Test开关的Java类。

  • */Test.java:任何子目录下所有命名以Test结尾的Java类。

  • */TestCase.java:任何子目录下所有命名以TestCase结尾的Java类。

maven-surefire-plugin 插件应用:

1.跳过测试

跳过测试运行 mvn package -DskipTests

或者通过 pom 提供该属性:

      org.apache.maven.plugins      maven-surefire-plugin      2.5                true        

跳过测试代码的编译 mvn package -Dmaven.test.skip=true

或者通过 pom 提供该属性:

      org.apache.maven.plugin      maven-compiler-plugin      2.1                true        

2.动态指定要运行的测试用例

mvn test -Dtest=RandomGeneratorTest

也可以使用通配符:

mvn test -Dtest=Random*Test

或者也可以使用","号指定多个测试类:

mvn test -Dtest=Random*Test,AccountCaptchaServiceTest

如果没有指定测试类,那么会报错并导致构建失败:

mvn test -Dtest

这时候可以添加 -DfailIfNoTests=false 参数告诉 maven-surefire-plugin 即使没有任何测试也不要报错:

mvn test -Dtest -DfailIfNoTests=false

3.包含与排除测试用例

      org.apache.maven.plugins      maven-surefire-plugin      2.5                              **/*Tests.java                                  **/*ServiceTest.java              **/TempDaoTest.java                  

关于"SpringBoot单元测试如何实现"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

测试 文件 生成 覆盖率 命令 报告 编译 单元 数据 配置 代码 参数 插件 运行 信息 周期 子目 子目录 就是 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百度信息服务器客服电话 两年软件开发经验事业编 悬挂式车路协同服务器收费 数据库字段来源 计算机网络技术测试软件 江苏推荐的软件开发创新服务 深圳紫塞风韵网络技术有限公司 湖南网络安全培训线上学习 锐捷服务器认证失败 僵尸作战模拟黑洞枪服务器介绍 首都网络安全期 为什么国外游戏都没有服务器 广西数据网络技术分类设计 房山回收二手服务器新报价 数据库原理单选题 医院网络安全自查情况表 打开别人的表格看不了数据库 泛微服务器维修公司地址电话 中国服务器厂商概论 app软件开发教程 服务器主板 家用 数据库上传与下载的区别 僵尸作战模拟黑洞枪服务器介绍 淘宝数据导入服务器无法解析 江苏运营网络安全工程联系人 我的世界服务器非常混乱 高校网络安全宣传活动总结 游戏软件开发的语言 k8s服务器最低要求 计算机保护账户数据库的密码
0