您如何测试调用 Go 中另一个 API 端点的服务?

How do you test a service that makes call to another API endpoint in Go?

我有一个使用无限循环创建的简单服务来定期调用某个 HTTP API,在包 aservice 中实现。我在那里创建了一个 Service 结构。通常,对于 运行 该服务,我公开了一个 StartService 方法,该方法用于同步 运行 该服务。然后,包的用户可以 运行 使用 goroutine。我的问题是,你如何为这种场景编写测试?

你运行整个系统和"mock" API?我听说使用第三方服务的代码不需要测试,但整个 aservice 包可能只包含 StartServiceShutdown 方法。其余的未导出 functions/methods,因此无法单独测试。如果是这样那我根本就不能写任何测试了?

使用 Go,您将在模拟外部 http 请求时获得很棒的体验。长话短说,只需将基础 url 替换为 net/http/httptest 包中的服务器 url。 您可以模仿 Google 模拟其外部请求的方式,例如在 google 地图 here.

中探索测试
server := mockServer(200, response)
defer server.Close()
c, _ := NewClient(WithAPIKey(apiKey), WithBaseURL(server.URL))
r := &DirectionsRequest{
    Origin:      "Google Sydney",
    Destination: "Glebe Pt Rd, Glebe",
    Mode:        TravelModeTransit,
}

resp, _, err := c.Directions(context.Background(), r) 
// your assertions goes here


 // Create a mock HTTP Server that will return a response with HTTP code and body.
func mockServer(code int, body string) *httptest.Server {
    server := mockServerForQuery("", code, body)
    return server.s
}

func mockServerForQuery(query string, code int, body string) *countingServer {
    server := &countingServer{}

    server.s = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if query != "" && r.URL.RawQuery != query {
            dmp := diffmatchpatch.New()
            diffs := dmp.DiffMain(query, r.URL.RawQuery, false)
            log.Printf("Query != Expected Query: %s", dmp.DiffPrettyText(diffs))
            server.failed = append(server.failed, r.URL.RawQuery)
            http.Error(w, "fail", 999)
            return
        }
        server.successful++

        w.WriteHeader(code)
        w.Header().Set("Content-Type", "application/json; charset=UTF-8")
        fmt.Fprintln(w, body)
    }))

    return server
}