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

AssertJ中assertThatCode()与assertThatThrownBy()的区别是什么?

AssertJ中assertThatCode(…).isInstanceOf(…)与assertThatThrownBy(…).isInstanceOf(…)的区别

两者看似功能重叠,但核心设计意图和默认行为有明显差异:

1. 设计初衷与默认校验逻辑

  • assertThatThrownBy(…)是专门为验证“代码块必须抛出异常”而生的工具。它的第一逻辑就是校验代码块是否抛出了异常——如果没抛,断言直接失败,不会走到后续的isInstanceOf校验。只有代码块抛出了异常,才会继续验证异常类型是否匹配。
  • assertThatCode(…)是通用的代码块断言工具,默认允许代码块正常执行不抛出异常。只有当你追加.isInstanceOf(…)这类异常校验时,它才会检查代码块是否抛出了指定类型的异常;如果没抛,断言才会失败。

2. 异常存在性的前置校验差异

用assertThatThrownBy(…).isInstanceOf(…)时,你不需要额外确认异常是否存在,方法本身就已经做了前置校验——它默认要求代码块必须抛出异常。而assertThatCode(…).isInstanceOf(…)只是在代码块执行后,校验“如果有异常,是否是指定类型”,同时也会校验“是否确实抛出了异常”。

3. 链式调用的语义合理性

你提到的assertThatThrownBy()支持doesNotThrowAnyException(),这是AssertJ提供的反向语义支持,但从命名和设计初衷看,这种用法非常反直觉——毕竟assertThatThrownBy的名字就指向“要抛出异常”,用它来验证不抛异常,远不如assertThatCode(…).doesNotThrowAnyException()语义清晰。

assertThatCode()的链式调用则更灵活,既可以验证异常(.isInstanceOf、.hasMessage(…)等),也可以验证代码块正常执行的结果(.returns(…)、.doesNotThrowAnyException()等),是一个全能型的代码块断言工具。

4. 实际运行差异示例

验证抛出指定异常

两段代码在正常抛出异常时结果一致:

// assertThatThrownBy写法
assertThatThrownBy(() -> riskyMethod("bad-input"))
  .isInstanceOf(IllegalArgumentException.class);

// assertThatCode写法
assertThatCode(() -> riskyMethod("bad-input"))
  .isInstanceOf(IllegalArgumentException.class);

但如果riskyMethod("bad-input")没有抛出异常:

  • assertThatThrownBy会直接失败,提示:Expected code to throw an exception but it didn't
  • assertThatCode会失败,提示:Expecting code to throw an exception of type <java.lang.IllegalArgumentException> but it didn't throw any

验证不抛出异常

// 语义清晰的标准写法
assertThatCode(() -> safeMethod("good-input"))
  .doesNotThrowAnyException();

// 语义别扭但可运行的写法
assertThatThrownBy(() -> safeMethod("good-input"))
  .doesNotThrowAnyException();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:26:20