使用require()时,如何确保断言失败仍调用resp.Body.Close()?
解决Go API测试中断言失败时关闭响应Body的问题
可以利用Go的defer特性结合标记变量实现,完全不需要额外的条件判断,代码更简洁健壮:
func Invoke(ip RestParams, es int) *http.Response { client := &http.Client{} // 用ip初始化req resp, err := client.Do(req) // 这里处理err... shouldClose := true defer func() { if shouldClose { resp.Body.Close() } }() // 直接执行断言,失败会终止当前测试 require.Equal(ru.ts.T(), tp.expectedStatus, resp.StatusCode) // 断言成功时,标记不需要关闭Body,交给调用方处理 shouldClose = false return resp }
原理说明:
defer注册的匿名函数会在函数退出前必然执行,不管是正常返回,还是断言失败触发的测试终止(require.Equal失败会调用FailNow直接终止当前测试函数)。- 初始
shouldClose设为true,如果断言失败,shouldClose = false这行代码不会执行,defer函数就会关闭Body;如果断言成功,我们把标记改成false,返回resp时就不会关闭Body,符合原逻辑。
这样既去掉了冗余的if判断,又保证了所有异常场景下Body都会被正确关闭,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Datha
相关产品推荐
相关产品推荐

