在 golang 中使用示例正文字符串创建 http.Response 实例

Create http.Response instance with sample body string in golang

我愿意使用示例正文字符串在 golang 中创建示例 http.Response 实例。

问题是,它的主体 属性 接受 ReadCloser 实例。但作为一个虚拟响应实例,我想知道是否有一些技巧可以轻松设置它而无需设置所有流 read/close 部分。

根据Not_a_Golfer and JimB的建议:

io.ReadCloser 是一个接口,当 struct 实现了 ReadClose 函数时就满足了。

幸运的是,有 ioutil.NopCloser,它采用 io.Reader 并将其包装在 nopCloser 结构中,该结构实现了 ReadClose。但是,它的 Close 函数确实如名称所暗示的那样 nothing

这是一个例子:

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    t := http.Response{
        Body: ioutil.NopCloser(bytes.NewBufferString("Hello World")),
    }

    buff := bytes.NewBuffer(nil)
    t.Write(buff)

    fmt.Println(buff)
}

要玩代码,请单击 here

这应该有效..

func main(){

    go serveHTTP(*port, *host)

    select {}
}

func serveHTTP(port int, host string) {

    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        requestHandler(w, r)
    })

    addr := fmt.Sprintf("%v:%d", host, port)
    server := &http.Server {
        Addr:           addr,
        Handler:        mux,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }

    err := server.ListenAndServe()
    log.Println(err.Error())
}

func requestHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, `Success!`)
}

进一步的顶部答案,我发现为了让客户将响应视为真实文章,它需要更完整地形成。对于正常 (200) 响应,我执行以下操作:

body := "Hello world"
t := &http.Response{
  Status:        "200 OK",
  StatusCode:    200,
  Proto:         "HTTP/1.1",
  ProtoMajor:    1,
  ProtoMinor:    1,
  Body:          ioutil.NopCloser(bytes.NewBufferString(body)),
  ContentLength: int64(len(body)),
  Request:       req,
  Header:        make(http.Header, 0),
}

然后你可以,例如,添加 headers (带有 401 状态代码,请求授权,比方说)。 req 是您要为其生成响应的 http.Request

是的,ioutil.NopCloser正是我所需要的!

我正在尝试测试一种方法,该方法为社交连接端点执行对 facebook API 的调用(通过辅助函数),我想模拟来自辅助函数的 facebook 响应,所以我的解决方案如下:

预期的 facebook 响应(转换为我自己的 UserData 结构)是:

UserData {
    ID:        facebookID,
    Email:     email,
    FirstName: firstName,
    LastName:  lastName,
}

所以我创建了这样的预期响应:

fbUserData, _ := json.Marshal(UserData{
    ID:        facebookID,
    Email:     email,
    FirstName: firstName,
    LastName:  lastName,
})
fbUserDataResponse := &http.Response{
    Body: ioutil.NopCloser(bytes.NewBufferString(string(fbUserData))),
}

然后我可以像这样模拟调用 facebook API 方法的响应:

s.fbGateway.EXPECT().ExecuteGetQuery(userUrl).Return(fbUserDataResponse, nil).Times(1)

这里的重点是,这实际上是关于模拟 return *http.Response 数据的任何类型的函数(在我的例子中,我通过一个辅助函数调用 facebook API return 是 http 响应,如上所述)。