Spring Boot 集成 JUnit5,更优雅单元测试!

Java单元测试实战:JUnit 5、Mockito与Spring Boot Test黄金组合详解 单元测试是软件工程中验证代码逻辑正确性的基础实践,其核心原理在于隔离被测单元,通过预设输入验证预期输出,从而确保代码模块的独立可靠性。这一技术能显著提升代码质量、降低回归错误风险,并支持持续集成与重构。在Java生态中,JUnit 5作为现代测试框架提供了声明式测试生命周期管理与丰富断言,而Mockito则通过模拟(Mock)和打桩(Stub)机制处理外部依赖,实现隔离测试。结合Spring Boot Test的测试切片(如@WebMvcTest、@DataJpaTest)与集成支持,开发者能高效构建从数据 阅读详情

来源:cnblogs.com/haixiang/p/13812363.html

为什么使用JUnit5

  • JUnit4被广泛使用,但是许多场景下使用起来语法较为繁琐,JUnit5中支持lambda表达式,语法简单且代码不冗余。

  • JUnit5易扩展,包容性强,可以接入其他的测试引擎。

  • 功能更强大提供了新的断言机制、参数化测试、重复性测试等新功能。

  • ps:开发人员为什么还要测试,单测写这么规范有必要吗?其实单测是开发人员必备技能,只不过很多开发人员开发任务太重导致调试完就不管了,没有系统化得单元测试,单元测试在系统重构时能发挥巨大的作用,可以在重构后快速测试新的接口是否与重构前有出入。

简介

图片

如图,JUnit5结构如下:

  • JUnit Platform :这是Junit提供的平台功能模块,通过它,其它的测试引擎都可以接入Junit实现接口和执行。

  • JUnit JUpiter :这是JUnit5的核心,是一个基于JUnit Platform的引擎实现,它包含许多丰富的新特性来使得自动化测试更加方便和强大。

  • JUnit Vintage :这个模块是兼容JUnit3、JUnit4版本的测试引擎,使得旧版本的自动化测试也可以在JUnit5下正常运行。

依赖引入

我们以SpringBoot2.3.1为例,引入如下依赖,防止使用旧的junit4相关接口我们将其依赖排除。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

常用注解

  • @BeforeEach:在每个单元测试方法执行前都执行一遍

  • @BeforeAll:在每个单元测试方法执行前执行一遍(只执行一次)

  • @DisplayName("商品入库测试"):用于指定单元测试的名称

  • @Disabled:当前单元测试置为无效,即单元测试时跳过该测试

  • @RepeatedTest(n):重复性测试,即执行n次

  • @ParameterizedTest:参数化测试,

  • @ValueSource(ints = {1, 2, 3}):参数化测试提供数据

断言

JUnit Jupiter提供了强大的断言方法用以验证结果,在使用时需要借助java8的新特性lambda表达式,均是来自org.junit.jupiter.api.Assertions包的static方法。

assertTrue`与`assertFalse`用来判断条件是否为`true`或`false
Copy    @Test
    @DisplayName("测试断言equals")
    void testEquals() {
        assertTrue(3 < 4);
    }
assertNull`与`assertNotNull`用来判断条件是否为·`null
    @Test
    @DisplayName("测试断言NotNull")
    void testNotNull() {
        assertNotNull(new Object());
    }

assertThrows用来判断执行抛出的异常是否符合预期,并可以使用异常类型接收返回值进行其他操作

    @Test
    @DisplayName("测试断言抛异常")
    void testThrows() {
        ArithmeticException arithExcep = assertThrows(ArithmeticException.class, () -> {
            int m = 5/0;
        });
        assertEquals("/ by zero", arithExcep.getMessage());
    }

assertTimeout用来判断执行过程是否超时

    @Test
    @DisplayName("测试断言超时")
    void testTimeOut() {
        String actualResult = assertTimeout(ofSeconds(2), () -> {
            Thread.sleep(1000);
            return "a result";
        });
        System.out.println(actualResult);
    }

assertAll是组合断言,当它内部所有断言正确执行完才算通过

    @Test
    @DisplayName("测试组合断言")
    void testAll() {
        assertAll("测试item商品下单",
                () -> {
                    //模拟用户余额扣减
                    assertTrue(1 < 2, "余额不足");
                },
                () -> {
                    //模拟item数据库扣减库存
                    assertTrue(3 < 4);
                },
                () -> {
                    //模拟交易流水落库
                    assertNotNull(new Object());
                }
        );
    }

重复性测试

在许多场景中我们需要对同一个接口方法进行重复测试,例如对幂等性接口的测试。

JUnit Jupiter通过使用@RepeatedTest(n)指定需要重复的次数

    @RepeatedTest(3)
    @DisplayName("重复测试")
    void repeatedTest() {
        System.out.println("调用");
    }
图片

参数化测试

参数化测试可以按照多个参数分别运行多次单元测试这里有点类似于重复性测试,只不过每次运行传入的参数不用。需要使用到@ParameterizedTest,同时也需要@ValueSource提供一组数据,它支持八种基本类型以及String和自定义对象类型,使用极其方便。

    @ParameterizedTest
@ValueSource(ints = {1, 2, 3})
@DisplayName("参数化测试")
    void paramTest(int a) {
            assertTrue(a > 0 && a < 4);
        }

内嵌测试

JUnit5提供了嵌套单元测试的功能,可以更好展示测试类之间的业务逻辑关系,我们通常是一个业务对应一个测试类,有业务关系的类其实可以写在一起。这样有利于进行测试。而且内联的写法可以大大减少不必要的类,精简项目,防止类爆炸等一系列问题。

@SpringBootTest
@AutoConfigureMockMvc
@DisplayName("Junit5单元测试")
public class MockTest {
    //....
    @Nested
    @DisplayName("内嵌订单测试")
    class OrderTestClas {
        @Test
        @DisplayName("取消订单")
        void cancelOrder() {
            int status = -1;
            System.out.println("取消订单成功,订单状态为:"+status);
        }
    }
}
END

JUnit5单元测试实战:从架构解析到Spring Boot集成 单元测试是保障软件质量、提升代码可维护性的核心工程实践,其核心原理在于通过隔离和自动化验证代码单元的行为是否符合预期。在Java生态中,JUnit作为事实上的标准测试框架,其技术价值在于为开发者提供了一套标准化、可扩展的测试编写与执行模型。JUnit 5作为新一代框架,通过清晰的三层架构(Platform、Jupiter、Vintage)和强大的扩展模型,显著提升了测试的灵活性与表达能力,尤其适合在现代Java项目及微服务架构中构建健壮的测试套件。其应用场景广泛,从简单的工具类验证到复杂的Spring Bo 阅读详情

相关推荐

spring-boot思维导图完整知识点脑图教程

这里包含了springboot的创建,参数,配置,数据库集成,部署,拦截器等开发中常用的信息。如有错漏更正欢迎来信307793969@qq.com

有啥不同?来看看Spring Boot 基于 JUnit 5 实现单元测试

作者:又语www.jianshu.com/p/4648fd55830e本文介绍 Spring Boot 2 基于 JUnit 5 的单元测试实现方案。目录 简介JUnit 4 和 JUn...

Java知音 1653

RFSOC实战解析(一):深入RF Data Converter的时钟与数据接口设计

本文深入解析RFSOC中RF Data Converter的时钟与数据接口设计,涵盖GHz采样、数据流处理、时钟树同步及AXI-Stream接口实战。通过详细案例和调试技巧,帮助工程师高效配置IP核,优化ADC/DAC性能,解决跨时钟域和信号完整性等关键问题。

weixin_30955617的博客 474

关于Junit的自我理解(思维导图形式)

程序员贺加贝的博客 214

深入解析组合逻辑环(combinational loop)的成因与解决方案

本文深入解析了数字电路设计中组合逻辑环(combinational loop)的成因与危害。通过边沿检测和中断轮询(round_robin)仲裁器等实例,揭示了代码如何意外形成环路,并对比了插入触发器、重构逻辑以及状态机思维三种核心解决方案,帮助硬件工程师从根本上避免这一常见设计陷阱,确保电路稳定可靠。

weixin_28278377的博客 315

在不同版本Python中安装PyQT5及PyQT5-Tools

在不同版本Python中安装PyQT5及PyQT5-Tools

zoomgu680的博客 2万+

SpringBoot思维导图(SpringBoot基础部分汇总)

SpringBoot第一谈(第一个SpringBoot项目、核心配置文件properties(yml、yaml)、集成jsp) SpringBoot第二谈SpringBoot的web开发(集成MyBtis、SpringBoot 下的SpringMVC、SpringBoot开发RESTFul风格、集成Redis) SpringBoot第三谈(Spring Boot 集成 Dubbo、Spring Boot 非 web 应用程序、SpringBoot 启动Logo修改关闭) SpringBoot第四谈(spr.

小游子YKY的博客 1万+

【2022KaliLinux】openvas/gvm 没有scan configs 或者是 scan config error “XXXXXXXXXXX”

gvm/openvas的configuration的scan config为空

zbossz的学习小分队 3607

idea 使用junit5的坑。

idea 2016版本开始支持junit5,最好是2017.3。官方原文: IntelliJ IDEA releases prior to IDEA 2017.3 bundle specific versions of JUnit 5. Thus, if you want to use a newer version of JUnit Jupiter, execution of tests wit...

wzl1369248650的博客 9884

Linux内核驱动模型--PCIe(PCI Express)驱动​​

本文系统介绍了Linux内核中PCIe驱动的设计与实现。首先从架构定位入手,指出PCIe驱动基于PCI子系统扩展支持高速、低功耗特性。核心数据结构struct pci_driver包含设备匹配表id_table、生命周期函数probe/remove等关键组件。文章详细解析了驱动与设备的绑定流程、资源管理机制,并重点阐述了MSI-X中断、电源管理、热插拔和多队列等高级特性实现方案。最后提供了lspci、dmesg等调试工具的使用方法,总结了PCIe驱动在支持高性能设备中的关键作用。全文通过架构设计、核心结构、

amy_mhd的博客 429

GPU 运维实战:H100/H800/B300 换卡与压测

(烧多久、看什么、什么算合格)。文末还给了一个能直接跑的验收判定脚本,三个真实场景的裁决输出都在。

老韩的Linux云计算架构师进阶之路 280

Spring Boot 集成 JUnit5,更优雅单元测试!,7年老软件测试一次操蛋的面试经历

ValueSource(ints = {1, 2, 3}):参数化测试提供数据。@DisplayName(“商品入库测试”):用于指定单元测试的名称。@BeforeEach:在每个单元测试方法执行前都执行一遍。@RepeatedTest(n):重复性测试,即执行n次。@DisplayName(“测试断言NotNull”)@DisplayName(“测试断言equals”)@DisplayName(“测试断言抛异常”)@DisplayName(“测试断言超时”)@DisplayName(“测试组合断言”)

m0_57473261的博客 893

计算机视觉与深度学习 | 基于Matlab的多特征融合可视化指纹识别系统(附完整代码)

此系统展示了一个完整的指纹识别流程,实际应用中可以根据需求进一步优化算法,如改进方向场计算、增加脊线频率特征、使用更精确的匹配算法等。

尘世冰封的专栏 362
上一篇: 蚂蚁开源增强版 SpringBoot,都有哪些骚能力?
下一篇: SQL 语句中 where 条件后 写上 1=1 是什么意思!
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值