Go语言 如何测试运行服务器的函数

14ifxucb  于 2023-01-10  发布在  Go
关注(0)|答案(1)|浏览(196)

我有一个名为Server的结构体,它有以下方法:

func (s *Server) Run(addr string) error {
    return http.ListenAndServe(addr, s)
}

下面是我通常测试这类函数的方法之一:

func TestServer_Run(t *testing.T) {
    srv := NewServer()

    go srv.Run(":2376")

    // Give server sometime to start
    time.Sleep(20*time.Millisecond)

    // Send some request to server and test the result.
}

我不想测试端点,我只想看看服务器是否正常运行。
但我觉得这种方式不太好,因为我需要等待20毫秒,服务器可能会启动得更早,我在这里浪费了一些时间。
此外,服务器启动速度更快,但我必须休眠20毫秒,所以我确信服务器已经启动,现在我可以开始使用服务器。
测试这样的函数最好的方法是什么?实际上如何避免time.Sleep()

nwo49xxi

nwo49xxi1#

您需要先启动TCP侦听器,然后您可以在服务器启动时发出HTTP请求。服务器准备就绪后,将立即处理该请求。
实际上,另一个问题是如何在测试结束时停止服务器。
下面是如何实现这两个目标的示例:

func TestServer_Run(t *testing.T) {
    l, err := net.Listen("tcp", "localhost:3000")
    require.NoError(t, err)

    r := http.NewServeMux()
    r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        _, _ = w.Write([]byte("Hello!"))
    })
    server := &http.Server{Handler: r}
    defer server.Close()
    go func() {
        if err := server.Serve(l); err != http.ErrServerClosed {
            panic(err)
        }
    }()

    res, err := http.Get("http://localhost:3000")
    require.NoError(t, err)

    body, err := io.ReadAll(res.Body)
    require.NoError(t, err)
    require.Equal(t, "Hello!", string(body))
}

相关问题