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

如何在Spock中处理意外异常?优化测试失败输出可读性

在Spock中自定义意外异常的失败信息

要让Spock测试抛出异常时的失败信息更可读,针对HttpClientErrorException这类带额外信息的异常,你可以通过显式捕获异常并构造自定义断言信息来实现,以下是两种实用方案:

方案一:直接在测试用例中处理

把原有的noExceptionThrown()替换为异常捕获逻辑,针对HttpClientErrorException提取状态码和响应体,输出定制化信息:

when:
restTemplate.getForObject(url, String)

then:
def thrownException = thrown()
if (thrownException instanceof HttpClientErrorException) {
    def httpEx = thrownException as HttpClientErrorException
    assert false : """Expected no exception to be thrown, but got 'HttpClientErrorException'
  Status-Code: ${httpEx.statusCode.value()}
  Body: '${httpEx.responseBodyAsString}'"""
} else {
    assert false : "Expected no exception to be thrown, but got '${thrownException.getClass().simpleName}'"
}

方案二:封装复用的辅助方法

如果多个测试用例都需要这个功能,可以把逻辑封装成辅助方法,放在测试基类里供所有用例调用:

1. 定义辅助方法

def noExceptionThrownWithDetailedMessage() {
    def exception = thrown()
    String errorMessage
    if (exception instanceof HttpClientErrorException) {
        def httpEx = (HttpClientErrorException) exception
        errorMessage = """Expected no exception to be thrown, but got 'HttpClientErrorException'
  Status-Code: ${httpEx.statusCode.value()}
  Body: '${httpEx.responseBodyAsString}'"""
    } else {
        errorMessage = "Expected no exception to be thrown, but got '${exception.getClass().simpleName}'"
    }
    throw new AssertionError(errorMessage, exception)
}

2. 在测试用例中调用

when:
restTemplate.getForObject(url, String)

then:
noExceptionThrownWithDetailedMessage()

这两种方式都会在测试失败时输出你期望的格式信息,既保留了异常的堆栈信息(通过把原异常作为AssertionError的cause),又补充了HttpClientErrorException特有的状态码和响应体细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:06:21