用例写 assertThrows(Exception.class, ...),实际抛的是 NullPointerException,本该是 IllegalArgumentException,测试照样通过。乍看像缓存或者权限的锅,追下去往往不是。
assertThrows(IllegalArgumentException.class,
() -> service.create(null));
追下去是这么回事:父类型能接住所有子类,断言只验证有异常,没验证是哪一种。错误类型被掩盖,调用方按约定写的捕获逻辑就失效了。
「异常类型未断言」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
权限不要一口气开到最大,先加到够用再往上试,范围小才好收。
具体做法是,断言具体异常类型 不写 Exception 或 RuntimeException;同时校验 message 里的关键字段;不该抛异常的分支用 assertDoesNotThrow;异常类型写进接口文档 用例跟着改。
验收就看一点,把实现改成抛 NPE 用例立即失败 提示类型不匹配。
