为了账号安全,请及时绑定邮箱和手机立即绑定

去关闭僵局

去关闭僵局

C#
心有法竹 2021-11-15 15:57:31
尝试在 Go 测试中模拟 http 响应。如果我运行它,下面的代码片段永远不会终止去测试example.com/auth/...package auth_testimport (    "testing"    "net/http/httptest"    "net/http")func TestAuthorization(t *testing.T) {    t.Log("Should return 401 when Gateway returns 401")    {        url := oneOffUrlWithResponseCode(http.StatusUnauthorized)        request, _ := http.NewRequest("GET", url, nil)        response, _ := http.DefaultClient.Do(request)        if response.StatusCode != http.StatusUnauthorized {            t.Fatalf("Response should be 401 (Unauthorized)")        }    }}func oneOffUrlWithResponseCode(responseCode int) string {    var server *httptest.Server    server = httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {        defer server.Close()        response.WriteHeader(responseCode)    }))    return server.URL}但是,如果我注释掉这一行延迟 server.Close()一切正常。理想情况下,我不想在 oneOffUrlWithResponseCode 函数之外“泄漏” *httptest.Server 并且显然在第一次请求后关闭它。为什么它永远不会终止?我究竟做错了什么?正确的做法是什么?
查看完整描述

1 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

程序不会因为死锁而终止(它与闭包无关)。您不能Close在处理程序内部调用,因为在内部Close等待所有处理程序完成。


修复它的最简单方法是在 oneOffUrlWithResponseCode 之外“泄漏”httptest.Server:


func TestAuthorization(t *testing.T) {

    ...

    server := oneOffUrlWithResponseCode(http.StatusUnauthorized)

    defer server.Close()

    request, _ := http.NewRequest("GET", server.URL, nil)

    ...

}


func oneOffUrlWithResponseCode(responseCode int) *httptest.Server {

    return httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {

        response.WriteHeader(responseCode)

    }))

}


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 161 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信