unit-testing - 去关闭死锁

标签 unit-testing go closures

尝试在 Go 测试中模拟 http 响应。如果我用

运行下面的代码片段,它永远不会终止

go test example.com/auth/...

package auth_test
import (
    "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
}

但是,如果我注释掉这一行

defer server.Close()

一切正常。

理想情况下,我不想在 oneOffUrlWithResponseCode 函数之外“泄漏”*httptest.Server 并在第一次请求后显然将其关闭。

为什么它永远不会终止?我究竟做错了什么?什么是正确的做法?

最佳答案

程序不会因为死锁而终止(这与闭包无关)。您不能在处理程序内部调用 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)
    }))
}

关于unit-testing - 去关闭死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33071854/

相关文章:

go - unique_index 和 unique 有什么区别?

ios - 具有常量值的映射在简单闭包中失败

javascript - Javascript 和 Lua 闭包的区别

java - 在 TestNG 中运行 Java 单元测试时消除对 testng.xml 的需求

unit-testing - 用于测试多个数据点的 rspec 设计模式

python - 如何使用 Django Rest Framework 对 HTTP 删除进行单元测试

http - 如何绕过分配将锁定值复制到 tr : net/http. Transport contains sync.Mutex

golang请求Orientdb http接口(interface)报错

c# - 如何对多线程场景中只执行一次的代码进行单元测试?

c# - 在 for 循环中分配委托(delegate)的问题