讲师中心 微信公众号
AI工具推荐 视频效率加速

JUnit 5 中断言异常消息匹配多个可能顺序的字符串

风瑶大大_5497

风瑶大大_5497

发布时间:2026-01-24 17:11:16

|

230人浏览过

|

来源于php中文网

原创

JUnit 5 中断言异常消息匹配多个可能顺序的字符串

在 junit 5 测试中,当被测方法抛出的异常消息包含动态拼接的集合元素(如 `b, c, d`)且顺序不确定时,直接用 `assertthrows(..., "expected message")` 会因元素遍历顺序不稳定而偶发失败;本文提供两种稳定、原生、无需第三方库的解决方案:固定迭代顺序构造输入数据,或对异常消息进行结构化解析断言。

在使用 Preconditions.checkArgument 等校验逻辑时,若错误消息依赖 Set 的 stream().filter(...).iterator() 遍历结果(如 Joiner.on(", ").join(...)),其输出顺序由底层 Set 实现决定。HashSet 不保证迭代顺序,导致测试中异常消息如 "The strings b, c, d..." 可能变为 "The strings d, b, c...",使基于完整字符串匹配的 assertThrows 断言不可靠。

✅ 方案一:控制输入,确保顺序可预测(推荐)

最简洁、可维护性最高的方式是在测试中主动提供有序集合,而非依赖实现细节。LinkedHashSet 按插入顺序迭代,完全符合需求:

@Test
void funcSubSet_throwsWithConsistentMessage() {
    // 使用 LinkedHashSet 替代 HashSet,保证 filter 后 stream 的顺序稳定
    Set<String> setA = new LinkedHashSet<>(Arrays.asList("a", "b", "c", "d"));
    Set<String> setB = new LinkedHashSet<>(Arrays.asList("a"));

    // 注入到被测对象(假设 funcSubSet 支持参数化或可重写)
    // 或通过重构将集合作为参数传入:funcSubSet(setA, setB)

    IllegalArgumentException ex = assertThrows(
        IllegalArgumentException.class,
        () -> funcSubSet(setA, setB)
    );

    assertEquals(
        "The strings b, c, d are present in setA but not in setB",
        ex.getMessage()
    );
}
? 关键点:此方案要求被测方法支持外部传入集合(即解耦数据构造与业务逻辑),这既是测试友好的设计,也提升了代码内聚性与可读性。

✅ 方案二:解析式断言 —— 对异常消息做语义校验

若无法修改被测方法签名或输入构造方式(如 setA/setB 是私有字段且不可注入),则应放弃“全字符串匹配”,转为校验消息结构 + 关键内容存在性:

Audio Upload Aioz Stream Free
Audio Upload Aioz Stream Free

基于 AIOZ Stream API 的免费音频上传技能,通过三步流程(Create → Upload Part → Complete)将本地音频文件上传至 AIOZ 流媒体平台。支持默认快速上传方式,使用默认编码配置,上传完成后返回 HLS 流媒体播放链接。使用 API Key (stream-publ...)进行认证。

下载
@Test
void funcSubSet_throwsWithCorrectContentRegardlessOfOrder() {
    Exception ex = assertThrows(Exception.class, () -> funcSubSet());

    String msg = ex.getMessage();

    // 校验固定前缀与后缀
    assertTrue(msg.startsWith("The strings "), "Message must start with 'The strings '");
    assertTrue(msg.endsWith(" are present in setA but not in setB"), 
               "Message must end with ' are present in setA but not in setB'");

    // 提取中间变量部分(去除前后固定文本)
    String variablesPart = msg.substring(
        "The strings ".length(),
        msg.length() - " are present in setA but not in setB".length()
    ).trim();

    // 分割并校验每个缺失元素是否都存在(忽略顺序和空格)
    Set<String> expectedMissing = Set.of("b", "c", "d");
    Set<String> actualMissing = Arrays.stream(variablesPart.split(",\s*"))
                                      .map(String::trim)
                                      .collect(Collectors.toSet());

    assertEquals(expectedMissing, actualMissing, 
                 "Missing elements mismatch: expected " + expectedMissing + ", got " + actualMissing);
}

该方案完全基于 JUnit 5 原生 Assertions,不引入 AssertJ、Hamcrest 等额外依赖,同时具备强健性:即使消息中多出空格、换行或标点微调,只要语义正确即可通过。

⚠️ 注意事项与最佳实践

  • 避免 HashSet 在测试敏感路径中:生产代码中若消息顺序影响用户体验或日志分析,也建议统一使用 LinkedHashSet 或 TreeSet(按字典序)。
  • 不要用 contains() 粗粒度校验:例如 assertTrue(msg.contains("b") && msg.contains("c")) 易受误匹配干扰(如 "ab" 被误认为含 "b"),应先分割再精确比对。
  • 优先重构而非绕过问题:异常消息顺序不可控本质是测试脆弱性的信号,推动将集合构造逻辑外移,比在测试中不断修补断言更可持续。

综上,控制输入顺序是首选策略;结构化解析是兜底方案。二者均立足 JUnit 5 原生能力,兼顾可靠性、可读性与工程可维护性。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
软件测试常用工具
软件测试常用工具

软件测试常用工具有Selenium、JUnit、Appium、JMeter、LoadRunner、Postman、TestNG、LoadUI、SoapUI、Cucumber和Robot Framework等等。测试人员可以根据具体的测试需求和技术栈选择适合的工具,提高测试效率和准确性 。

4890

2023.10.13

java测试工具有哪些
java测试工具有哪些

java测试工具有JUnit、TestNG、Mockito、Selenium、Apache JMeter和Cucumber。php还给大家带来了java有关的教程,欢迎大家前来学习阅读,希望对大家能有所帮助。

3261

2023.10.23

Java 单元测试
Java 单元测试

本专题聚焦 Java 在软件测试与持续集成流程中的实战应用,系统讲解 JUnit 单元测试框架、Mock 数据、集成测试、代码覆盖率分析、Maven 测试配置、CI/CD 流水线搭建(Jenkins、GitHub Actions)等关键内容。通过实战案例(如企业级项目自动化测试、持续交付流程搭建),帮助学习者掌握 Java 项目质量保障与自动化交付的完整体系。

1146

2025.10.24

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1818

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2864

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6204

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5989

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

7614

2024.03.22

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

40

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn