You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在开发周期中识别未添加断言的Assertj assertThat调用?

当然可以!这种只调用assertThat(object.getField())却不跟进具体断言的测试完全是无效的——它根本没验证任何逻辑,只是创建了一个Assertj断言对象就完事了,相当于白写。下面给你几种在开发周期里揪出这类问题的方案,包括你提到的自定义Sonar规则的具体实现思路:

方案一:IDE静态代码检查(实时反馈,开发阶段就堵漏洞)

很多主流IDE都能快速配置这类检查,让开发者写代码时立刻发现问题:

  • 以IntelliJ IDEA为例,你可以创建结构化搜索检查:
    1. 打开 File > Settings > Editor > Inspections > General > Structural Search Inspection
    2. 点击「Add」新建搜索模板,模板内容写:assertThat($expression$);
    3. 设置约束:确保这个语句是独立的ExpressionStatement(也就是到assertThat()就结束,没有后续链式调用),$expression$可以匹配任意表达式
    4. 将这个检查的级别设为「Error」,这样IDE会实时标红这类无效代码
  • Eclipse也可以通过类似的自定义规则或者Assertj相关插件实现,核心思路都是识别孤立的assertThat()语句
方案二:自定义SonarQube规则(团队级统一管控)

你提到的自定义Sonar规则完全可行,核心是识别那些调用完assertThat()后没有链式调用任何断言方法的孤立语句。具体实现步骤如下:

  1. 基于SonarJava API开发自定义规则:
    • 先熟悉SonarJava的规则开发框架,创建一个Java项目作为Sonar插件
  2. 分析Assertj的方法特征:
    • assertThat()方法返回的是Assertion的子类(比如ObjectAssert、StringAssert)
    • 有效的断言方法(比如isEqualTo()、isNull()、contains())要么返回void,要么返回当前断言对象用于链式调用
    • 我们要找的是:assertThat()调用直接作为一条语句结束,没有后续调用的情况
  3. 编写规则逻辑:
    • 遍历AST(抽象语法树)中的所有方法调用节点,找到方法名为assertThat的调用
    • 检查该节点的父节点:如果父节点是ExpressionStatement(说明这条语句到assertThat()就终止了),同时这个调用没有被赋值给变量(比如排除ObjectAssert<String> assert = assertThat(str);这种合法场景),就标记为违规
  4. 打包规则成Sonar插件,部署到团队的Sonar服务器,配置为强制检查的规则,这样代码提交后就能自动扫描出问题
方案三:CI阶段的字节码/静态扫描

如果不想依赖Sonar,也可以在CI构建阶段做检查:

  • 用ASM这类字节码工具扫描测试类的class文件,识别所有孤立的assertThat()调用
  • 或者写一个简单的JUnit扩展,在测试执行前后扫描测试类的字节码,一旦发现无效断言就抛出异常,阻断CI流程
  • 这种方案适合小型团队,或者需要在构建阶段直接拦截无效测试的场景
额外提醒:规范团队的Assertj使用习惯

其实最根本的是统一团队的测试规范:

  • 明确要求任何assertThat()调用必须紧跟至少一个断言方法,比如assertThat(user.getAge()).isGreaterThan(18);
  • 如果只是想验证表达式不抛出异常,应该用assertThatCode(() -> object.getField()).doesNotThrowAnyException();,而不是孤零零的assertThat(object.getField());

内容的提问来源于stack exchange,提问作者TomVW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:39:24