使用httptest服务多个处理程序以模拟多个请求

时间:2018-07-10 01:28:12

标签: go

我已经为此进行了全面的搜索,但找不到任何内容。

我有一个接受http.Client的结构,它发送几个GET请求。在我的测试中,我想模拟响应,以免发送实际请求。

目前,我已经弄清楚了如何仅处理1个请求,如下所示:

     ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        file, err := os.Open("./testdata/1.html")
        if err != nil {
            t.Error(err)
        }
        bytes, err := ioutil.ReadAll(file)
        if err != nil {
            t.Error(err)
        }
        w.Write(bytes)
    }))

   ts.Client() // Now I can inject this client into my struct.

因此,一旦模拟出该响应并且http客户端执行了一个新请求,我的测试就会在此之后发出实际请求。

如何允许多个处理程序,以便在调用http.Client.Get(...)时可以模拟多个响应?

2 个答案:

答案 0 :(得分:2)

ServeMux.Handle可用于设置服务器来处理多个请求,例如in this example

package main

import (
    "log"
    "net/http"
)

const addr = "localhost:12345"

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/hello", HandleHello)
    // other handlers can be assigned to separate paths
    log.Printf("Now listening on %s...\n", addr)
    server := http.Server{Handler: mux, Addr: addr}
    log.Fatal(server.ListenAndServe())
}

func HandleHello(w http.ResponseWriter, r *http.Request) {
    log.Printf("Hello!")
}

但是,老实说,您可能只想将http.Client抽象到您所创建的接口后面,然后将其存入一个测试实现中,即可返回您想要的结果。这样可以避免测试中HTTP通讯的开销。

答案 1 :(得分:1)

由于原始问题使用的是httptest.NewServer-您可以在httptest.Server函数上注册一个ServeMux,然后可以向该多路复用器添加多个路由:

mux := http.NewServeMux()

mux.HandleFunc("/someroute/", func(res http.ResponseWriter, req *http.Request) {
    ...do some stuff...
})
mux.HandleFunc("/someotherroute/", func(res http.ResponseWriter, req *http.Request) {
    ...do other stuff...
})

ts := httptest.NewServer(mux)
defer ts.Close()