Spring Assert(方法入参检测工具类-断言)

本文介绍如何使用Spring框架中的Assert类来进行方法参数的有效性检查,包括多种断言方法及其应用场景。
Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回。类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异常的方式拒绝后续处理。举一个例子:有一个根据文件名获取输入流的方法:InputStream getData(String file),为了使方法能够成功执行,必须保证 file 入参不能为 null 或空白字符,否则根本无须进行后继的处理。这时方法的编写者通常会在方法体的最前面编写一段对入参进行检测的代码,如下所示:

public InputStream getData(String file) {
    if (file == null || file.length() == 0|| file.replaceAll("\\s", "").length() == 0) {
        throw new IllegalArgumentException("file入参不是有效的文件地址");
    }

}

类似以上检测方法入参的代码是非常常见,但是在每个方法中都使用手工编写检测逻辑的方式并不是一个好主意。阅读 Spring 源码,您会发现 Spring 采用一个 org.springframework.util.Assert 通用类完成这一任务。

Assert 翻译为中文为“断言”,使用过 JUnit 的读者都熟知这个概念,它断定某一个实际的运行值和预期想一样,否则就抛出异常。Spring 对方法入参的检测借用了这个概念,其提供的 Assert 类拥有众多按规则对方法入参进行断言的方法,可以满足大部分方法入参检测的要求。这些断言方法在入参不满足要求时就会抛出 IllegalArgumentException。下面,我们来认识一下 Assert 类中的常用断言方法:
Spring Assert的所有方法:

 

 

断言方法 说明
1. notNull(Object object) 
当 object 不为 null 时抛出异常,notNull(Object object, String message) 方法允许您通过 message 定制异常信息。和 notNull() 方法断言规则相反的方法是 isNull(Object object)/isNull(Object object, String message),它要求入参一定是 null;

2. isTrue(boolean expression) / isTrue(boolean expression, String message) 
当 expression 不为 true 抛出异常;

3. notEmpty(Collection collection) / notEmpty(Collection collection, String message) 
当集合未包含元素时抛出异常。
notEmpty(Map map) / notEmpty(Map map, String message) 和 notEmpty(Object[] array, String message) / notEmpty(Object[] array, String message) 分别对 Map 和 Object[] 类型的入参进行判断;

4. hasLength(String text) / hasLength(String text, String message) 

当 text 为 null 或长度为 0 时抛出异常;

5. hasText(String text) / hasText(String text, String message) 

text 不能为 null 且必须至少包含一个非空格的字符,否则抛出异常;

6. isInstanceOf(Class clazz, Object obj) / isInstanceOf(Class type, Object obj, String message) 

如果 obj 不能被正确造型为 clazz 指定的类将抛出异常;

7. isAssignable(Class superType, Class subType) / isAssignable(Class superType, Class subType, String message) 

subType 必须可以按类型匹配于 superType,否则将抛出异常;

使用 Assert 断言类可以简化方法入参检测的代码,如 InputStream getData(String file) 在应用 Assert 断言类后,其代码可以简化为以下的形式:

public InputStream getData(String file){
    Assert.hasText(file,"file入参不是有效的文件地址");
    ① 使用 Spring 断言类进行方法入参检测

}

<think>嗯,用户这次想了解测试断言assert)的作用和用法。从用户的问题看,ta应该是在学习单元测试相关的内容,可能是个开发者,尤其是Java开发者,因为引用的资料都围绕Java的assert。用户提供的引用材料非常丰富,涵盖了从基础概念到具体框架的实现。引用1和4解释了assert的核心作用——验证程序假设,用于调试和测试;引用2和3展示了JUnit和Spring中的具体用法,包括不同断言方法;引用5则补充了C/C++中assert的注意事项,虽然用户主要问Java,但多语言对比也能帮助理解共性问题。需要重点梳理的是:测试中断言和开发中assert关键字的区别(这点引用4讲得很清楚,开发用的assert默认禁用,而测试框架的断言始终启用)。用户可能混淆了这两者,需要明确区分。回答结构上,考虑从四个层面展开:作用(为什么用)、常见方法(怎么用)、使用场景(何时用)、注意事项(避免踩坑)。特别是第三部分,用户提供的引用3中有大量示例代码,可以直接整合成表格,更直观展示不同断言方法的适用场景。最后生成的问题要有延续性:从基础用法进阶到异常处理(assertThrows)、最佳实践(避免副作用)、多框架对比等,这样用户如果学完了基础还能深。要确保每个知识点都有引用支撑,比如讲assertSame时标注引用3的示例。</think> 测试中的 `assert` 断言方法用于**验证测试结果是否符合预期**,是单元测试的核心工具。其作用与常见用法如下: --- ### **一、核心作用** 1. **验证预期结果** 通过比较实际输出与预期值,判断代码逻辑是否正确,例如: ```java @Test void testAddition() { int result = Calculator.add(2, 3); assertEquals(5, result); // 验证计算结果是否为5 } ``` 2. **检测程序假设** 确保代码执行过程中的关键条件成立(如非空、范围等),如: ```java @Test void testNotNull() { User user = userService.findById(1); assertNotNull(user); // 验证对象不为空[^4] } ``` 3. **快速定位错误** 若断言失败,测试框架会明确提示预期值与实际值的差异,加速调试[^1][^4]。 --- ### **二、常用断言方法及语法(以JUnit 5为例)** | **断言方法** | **作用** | **示例** | |--------------------|-----------------------------------|----------------------------------------------| | `assertEquals()` | 验证预期值与实际值相等 | `assertEquals(10, result)` | | `assertNotEquals()`| 验证预期值与实际值不相等 | `assertNotEquals(0, list.size())` | | `assertTrue()` | 验证条件为真 | `assertTrue(result > 0)` | | `assertFalse()` | 验证条件为假 | `assertFalse(user.isDeleted())` | | `assertNull()` | 验证对象为空 | `assertNull(errorMessage)` | | `assertNotNull()` | 验证对象非空 | `assertNotNull(response.getData())` | | `assertSame()` | 验证两个对象引用同一个实例 | `assertSame(expectedObj, actualObj)` | | `assertNotSame()` | 验证两个对象引用不同实例 | `assertNotSame(obj1, obj2)` | | **进阶方法** | | | | `assertThrows()` | 验证代码抛出指定异常 | `assertThrows(IllegalArgumentException.class, () -> method())`[^2] | | `assertTimeout()` | 验证代码在指定时间内完成 | `assertTimeout(Duration.ofMillis(100), () -> task())`[^2] | --- ### **三、典型使用场景** 1. **结果准确性校验** ```java @Test void testDiscount() { double price = 100.0; double discount = price * 0.8; assertEquals(80.0, discount); // 验证折扣计算正确 } ``` 2. **异常流程验证** ```java @Test void testInvalidInput() { assertThrows(InvalidDataException.class, () -> service.process(null)); // 验证空输触发异常[^3] } ``` 3. **状态变更检查** ```java @Test void testUserActivation() { user.activate(); assertTrue(user.isActive()); // 验证激活状态变更 } ``` --- ### **四、关键注意事项** 1. **避免副作用** 断言表达式**不应修改程序状态**(如 `assert(i++)`),否则禁用断言时可能导致逻辑错误[^5]。 2. **精确值比较** 浮点数比较需用 `assertEquals(expected, actual, delta)` 指定误差范围: ```java assertEquals(0.333, 1.0/3.0, 0.001); // 允许0.001误差 ``` 3. **启用断言** 开发阶段需通过JVM数 `-ea` 启用Java原生`assert`关键字(测试框架的断言始终启用)[^1][^4]。 --- ### **总结** 断言是测试代码的“自动化检查员”,通过预设条件快速捕捉逻辑错误。它既充当代码文档(明确预期行为)[^4],又是调试核心工具。正确使用断言可显著提升测试覆盖率和可靠性,尤其在持续集成流程中不可或缺。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值