0

0

JUnit 5 测试中验证异常消息包含多个可变顺序字符串的正确方法

聖光之護

聖光之護

发布时间:2026-01-24 17:04:01

|

393人浏览过

|

来源于php中文网

原创

JUnit 5 测试中验证异常消息包含多个可变顺序字符串的正确方法

本文介绍在 junit 5 中如何可靠地断言异常消息中包含若干无序字符串(如 "b, c, d"),避免因 `hashset` 迭代顺序不确定导致测试偶然失败。核心方案包括:使用 `linkedhashset` 控制顺序,或对捕获的异常消息进行结构化解析与子串/内容校验。

在单元测试中验证异常消息时,若消息内容依赖于 HashSet 等无序集合的遍历结果(例如 setA.stream().filter(...).collect(...)),其元素输出顺序不可预测,将直接导致基于完整字符串匹配的断言(如 assertThrows(..., "The strings b, c, d are..."))间歇性失败——这并非测试缺陷,而是设计隐患。

✅ 推荐方案一:从源头控制顺序(最佳实践)

修改被测代码的测试调用方式,传入有序集合替代 HashSet。例如,在测试中使用 LinkedHashSet 或 TreeSet:

@Test
void funcSubSet_throwsWithPredictableOrder() {
    final Set<String> setA = new LinkedHashSet<>(Arrays.asList("a", "b", "c", "d")); // 保持插入顺序
    final Set<String> setB = new LinkedHashSet<>(Arrays.asList("a"));

    // 通过依赖注入或重构使 funcSubSet 接收参数,而非硬编码
    Exception exception = assertThrows(IllegalArgumentException.class, 
        () -> funcSubSet(setA, setB));

    assertEquals("The strings b, c, d are present in setA but not in setB", 
                 exception.getMessage());
}
? 提示:将集合作为参数传入 funcSubSet(Set<String> setA, Set<String> setB) 不仅提升测试可控性,也显著增强方法内聚性与可复用性,符合“易测即易用”原则。

✅ 推荐方案二:对异常消息做语义化断言(无需修改被测代码)

当无法调整被测逻辑(如遗留系统)时,应避免强依赖完整消息字符串,转而校验消息结构 + 关键内容

VIVA
VIVA

一个免费的AI创意视觉设计平台

下载
@Test
void funcSubSet_throwsWithFlexibleMessage() {
    Exception exception = assertThrows(IllegalArgumentException.class, 
        () -> funcSubSet());

    String msg = exception.getMessage();

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

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

    // 3. 验证所有预期元素均存在(忽略顺序和分隔符细节)
    assertTrue(variablesPart.contains("b"), "Expected 'b' in message");
    assertTrue(variablesPart.contains("c"), "Expected 'c' in message");
    assertTrue(variablesPart.contains("d"), "Expected 'd' in message");

    // 可选:进一步验证是否仅含预期元素(防误报)
    Set<String> actualElements = Arrays.stream(variablesPart.split(",\s*"))
                                       .map(String::trim)
                                       .collect(Collectors.toSet());
    assertEquals(Set.of("b", "c", "d"), actualElements);
}

⚠️ 注意事项与避坑指南

  • 不要使用 hasMessage(String) 的精确匹配:Assertions.assertThrows(...).getMessage() 返回值不可控,直接比对完整字符串是反模式。
  • 慎用正则模糊匹配:如 matches("The strings [b,c,d,\s]+are present.*") 易受空格、换行、标点干扰,可维护性差。
  • 优先选择 LinkedHashSet 而非 TreeSet:前者保持插入顺序(符合测试预期),后者按字典序排序(可能引入意外行为)。
  • JUnit 5 原生支持足够强大:无需引入 AssertJ 等第三方库即可完成上述断言,降低项目依赖复杂度。

通过以上任一方案,均可彻底消除因集合迭代顺序不确定性引发的测试不稳定性,让异常消息验证既健壮又可读。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

463

2023.10.13

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

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

313

2023.10.23

Java 单元测试
Java 单元测试

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

30

2025.10.24

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1030

2023.08.02

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

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

760

2023.08.03

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

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

221

2023.09.04

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

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

1567

2023.10.24

字符串介绍
字符串介绍

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

649

2023.11.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
手把手实现数据传输编码
手把手实现数据传输编码

共1课时 | 768人学习

PHP自制框架
PHP自制框架

共8课时 | 0.6万人学习

【李炎恢】ThinkPHP8.x 后端框架课程
【李炎恢】ThinkPHP8.x 后端框架课程

共50课时 | 4.7万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号