springboot集成mockito和jacoco实践

JaCoCo、Mockito来做单元测试真香! JaCoCo、Mockito来做单元测试真香! 一、单元测试 1.1 单元测试说明 ​  ​  ​  ​ 定义:单元测试(unit testing)是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作,在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。   ​  ​  ​  优缺点: 单元测试从长期来看,可以提高代码质量,减少维护成本,减少调试时间,降低重构难度。但是 阅读详情

mockito,一款 spring 框架开发中常用的单元测试工具,junit亦然。在实践中二者经常混合使用,各司其职,共同完成测试任务。核心关系和分工如下:

工具

职责

在之前代码中的体现

JUnit

提供测试框架,管理测试生命周期(如 @Test、@BeforeEach),断言验证(如 assertEquals)。

1. 标记测试方法 (@Test) 2. 断言结果 (assertEquals) 3. 测试类的结构(如 class XxxTest)。

Mockito

模拟依赖对象(如 Service、DAO),验证交互行为(如 verify)。

1. 模拟 demoService (@Mock) 2. 验证方法调用 (verify(demoService).getDto())。

通常单元测试做完后还需要 “单测覆盖率” 的数据,类似在校时各类大小考试后的卷面评分,这个环节一般使用 jacoco。大型项目可能会使用 SonarQube(听说的,实际有没有我也不知道),这个不在此次讨论范围内。

本文开发版本前提:

JDK

spring-boot

spring-cloud

spring-cloud-alibaba

1.8

2.7.18

2021.0.9

2021.0.6.1

mockito 和 junit 依赖

官网:site.mockito.org/

微服务开发下的mockito已经集成在了spring-boot-start-test模块里,包括junit,因此不需要额外引入。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>3.5.0</version>
</dependency>

jacoco依赖

jacoco是用来计算代码覆盖率的,小型项目里常用的框架,如果是大规模项目就得用别的了,比如 SonarQube/SonarCloud。

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version> <!-- 使用最新版本 -->
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal> <!-- 在测试阶段注入 JaCoCo 代理 -->
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase> <!-- 在 test 阶段生成报告 -->
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

安装完后用 mvn clean test 在项目根目录下执行就能得到测试报告(前提是已经有单元测试类及代码)

如果要单独指定某一个子模块并屏蔽其他模块,可以用mvn clean test -pl module-name -am。最终生成的报告在目标模块下的 target/site/jacoco 文件夹里。

单元测试与集成测试

如果不想钻牛角尖的话,单元测试可以理解为多程序逻辑中各个“最小单元”的测试,这些最小单元可以被预设输入值和期望输出值,可以验证,这也就是 mockito 要做的事。

之所以说“如果不想钻牛角尖”,是因为我自己就思路打结过,毕竟单元可大可小,各功能之间又是调用来调用去的……

单元测试示例

单元测试与集成测试最直观的区别,在我看来就是类层面的注解。

//单元测试
@ExtendWith(MockitoExtension.class)
//集成测试
@ExtendWith(SpringExtension.class)
@SpringBootTest

正如前面表格所述,mockito 的作用是模拟依赖对象(如 Service、DAO),验证交互行为(如 verify),因此测试时,基本都是要假定输入与输出,再去执行。

以 controller 层的测试为例,测试的是 controller 的接口,但由于 controller 大多数时候调用了 service,所以还需要一个虚拟的 service,用来模拟不同的 service 返回结果在 controller 是否得到了正确处理。

简单写一个用于校验的 service,有多简单?直接返回 Boolean 结果。

@Service
public class DemoServiceImpl implements DemoService {
    
    @Override
    public boolean jiaoyanTest(){
        return true;
    }

controller 里调用它,并对不同的返回结果做处理——打印不同字符串。

@RestController
public class DemoController {

    @Autowired
    private DemoService demoService;

    @GetMapping(PREFIX+"/jianquan")
    public String jianquan(){
        String res = "通过";
        if (!demoService.jiaoyanTest()){
            res = "不通过";
        }
        System.out.println("jianquan执行结果:"+res);
        return res;
    }
}

在单元测试类里,就需要这么测试它。

@Mock
private DemoService demoService;
@InjectMocks
private DemoController demoController;
@Test
void test(){
    //模拟service返回true
    Mockito.when(demoService.jiaoyanTest()).thenReturn(true);
    String res = demoController.jianquan();
    assertEquals("通过",res);
    //模拟service返回false
    Mockito.when(demoService.jiaoyanTest()).thenReturn(false);
    res = demoController.jianquan();
    assertEquals("不通过",res);
}

执行结果就会是两个 assert 断言都正常通过——输入依照设定,输出符合预期,有什么理由不通过呢?

jianquan执行结果:通过
jianquan执行结果:不通过

如果颠倒断言的顺序而保持 mock 设定的顺序不变,这个逻辑必然出错。

jianquan执行结果:通过

org.opentest4j.AssertionFailedError: 
Expected :不通过
Actual   :通过
<Click to see difference>

执行结果也忠实地打印了实际效果:验证不通过,并且不再执行下一步校验(毕竟是故意写的错误逻辑)。第一行是 controller 内的打印结果,后面是断言的提示:期望返回应是“不通过”,但实际是“通过”,说明执行结果与期望不符。

集成测试示例

和平常启动项目时的写法基本一致。

@ExtendWith(SpringExtension.class)
@SpringBootTest
public class DemoControllerTest {
    @Autowired
    private DemoController demoController;

    @Test
    void test4(){
        // 调用真实的服务方法
        String res = demoController.jianquan();
        // 根据实际业务逻辑验证结果
        assertEquals("不通过", res); //
    }
}

总结

主要方便自己忘了的时候找回写法。

小试牛刀:spring boot项目集成jacoco jacoco不必多说,代码覆盖率工具。相比于其他java web项目,spring boot项目本身集成了tomcat,所以集成方法稍微区别于其他项目。 直接进入正题,在本地建一个spring boot项目,并创建一个名为HelloController的class,写两个hello world(网上很多现成的demo,可以直接拿来用) 成功启动main方法后浏览器访问127.0.0.1:8080... 阅读详情

相关推荐

springboot项目使用Junit5 + mockito + jacoco 实现单元测试以及代码覆盖率检查

springboot中使用junit、mock和jacoco实现单元测试以及代码覆盖率检查

wk_jl的博客 5626

SpringBoot日常:集成代码覆盖率测试工具JaCoCo

Jacoco是面向Java的开源代码覆盖率工具,Jacoco以java代理模式运行,它负责在运行测试时检测字节码。Jacoco会深入研究每个指令,并显示每个测试过程中要执行的行,为了收集覆盖率数据,Jacoco使用ASM即时进行代码检测,并在此过程中从JVM Tool Interface 接收事件,最终生成代码覆盖率报告。

qq_32590535的博客 5011

JavaWeb项目基石:Maven与单元测试的实战配置与高效集成

在Java企业级开发中,项目构建与自动化测试是保障软件质量的核心基础。Maven作为标准的项目对象模型(POM)和构建工具,通过pom.xml文件统一管理依赖、编译和打包,实现了项目结构的标准化与环境一致性,解决了依赖冲突和“在我机器上能跑”的协作难题。单元测试则通过JUnit等框架,在最小代码单元上验证逻辑正确性,提供快速反馈,防止回归错误。两者结合,形成了可重复、自动化的质量保障工作流。本文聚焦于JavaWeb项目,深入解析Maven的核心配置、仓库优化,并结合JUnit 5、Mockito以及Spri

diandingyin9417的博客 551

深入解析Spring Boot与JUnit 5的集成测试实践

提供了测试执行的基础设施。:包含了新的编程模型和扩展模型。:用于兼容旧版本的JUnit测试。JUnit 5支持Lambda表达式、嵌套测试、参数化测试等新特性,使得测试代码更加简洁和灵活。本文详细介绍了如何在Spring Boot项目中集成JUnit 5进行单元测试和集成测试,涵盖了测试框架的选择、测试代码的编写、Mockito的使用以及测试覆盖率分析等内容。通过合理的测试实践,可以显著提高代码的质量和可维护性。

intwei的博客 1300

SpringBoot单元测试实战:JUnit5+Mockito+MockMvc组合应用详解

单元测试是保障软件质量的核心实践,通过隔离被测代码与外部依赖,确保每个独立单元的行为符合预期。其原理在于利用测试框架组织用例,通过模拟(Mock)技术隔离数据库、API等不稳定依赖,从而构建快速、稳定的测试环境。这一技术价值在于提升代码可靠性、便于重构与持续集成。在Java生态中,SpringBoot项目的单元测试通常涉及Controller、Service等多层组件。针对这一场景,JUnit5作为现代测试框架提供了参数化测试等强大功能,而Mockito则擅长依赖隔离,能有效模拟Service层的外部调用。

weixin_30520015的博客 332

SpringBoot3与JUnit5实战:从单元测试到集成测试全解析

本文全面解析了SpringBoot3与JUnit5的实战应用,从单元测试到集成测试的完整流程。通过详细的代码示例和最佳实践,帮助开发者高效构建自动化测试体系,提升代码质量与稳定性。特别介绍了SpringBoot3默认集成JUnit5的优势,以及如何利用Mockito、AssertJ等工具链进行高效测试。

weixin_28839549的博客 369

Spring Boot测试驱动开发终极指南:从单元测试到集成测试的完整方法论

Spring Boot测试驱动开发(TDD)是保障应用质量的关键实践,通过先编写测试再实现功能的方式,能显著提升代码可靠性和可维护性。本文将带你掌握从单元测试到集成测试的完整方法论,让你轻松构建健壮的Spring Boot应用。 ## 为什么选择测试驱动开发? 测试驱动开发不仅是一种开发方式,更是一种思维模式。在Spring Boot项目中采用TDD有三大核心优势: - **提前暴露问题**

gitblog_00996的博客 1016

SpringBoot单元测试实战:JUnit5与Mockito构建高质量代码保障体系

单元测试作为软件质量保障的核心环节,通过隔离测试单个代码单元来验证其逻辑正确性。其原理在于模拟外部依赖,聚焦被测对象行为,确保代码变更不会引入回归缺陷。在工程实践中,单元测试能显著提升代码可维护性,降低缺陷修复成本,并为持续重构提供安全网。尤其在微服务与分布式架构盛行的当下,单元测试成为保障服务稳定性的基础手段。本文以SpringBoot项目为背景,深入讲解如何运用JUnit5进行生命周期管理、参数化测试,并结合Mockito实现依赖模拟与行为验证,通过实战演示如何构建高效可靠的测试套件,并合理运用测试覆盖

weixin_34377919的博客 442

Spring Boot与Spring MVC集成JUnit单元测试实战案例

在现代软件工程中,单元测试是保障代码质量的基石。它通过验证最小代码单元的正确性,有效拦截缺陷向生产环境扩散。对于Spring Boot应用而言,单元测试不仅是功能校验手段,更是设计优良架构的推动力。借助JUnit 5作为测试引擎核心,结合Mockito实现依赖隔离、AssertJ提升断言可读性,并利用H2内存数据库快速验证数据操作,形成了一套高效协同的测试技术栈。同时,遵循测试金字塔模型,强调底层单元测试的高覆盖率与快速反馈,为上层集成测试和端到端测试奠定稳定基础。

weixin_35749796的博客 834

Spring Boot 3.0 + Mockito 5.0实战:手把手教你写高覆盖率的Java单元测试

本文详细介绍了如何使用Spring Boot 3.0和Mockito 5.0编写高覆盖率的Java单元测试。从环境搭建、Mockito核心功能实战到Spring Boot测试新特性,全面覆盖单元测试的各个方面,帮助开发者提升代码质量和测试效率。特别适合Java开发者学习高效实践单元测试技巧。

weixin_28835583的博客 226

SpringBoot接入JaCoCo实践

SpringBoot接入JaCoCo实践

qq_16422103的博客 2779
上一篇: Java面试题及答案整理( 2025年最新版,持续更新)
下一篇: 基于Redisson的分布式锁
程序员职业指南
博客等级 码龄4年 2139粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值