【问题标题】:Create http.Response instance with sample body string in golang在 golang 中使用示例正文字符串创建 http.Response 实例
【发布时间】:2015-11-29 00:57:49
【问题描述】:

我愿意在 golang 中创建一个带有示例正文字符串的示例 http.Response 实例。

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

【问题讨论】:

  • 您可以扩展一个简单的字符串阅读器或使用虚拟Close 方法类似的东西。
  • 为你完成了:ioutiil.NopCloser
  • 现在你可以使用http.NoBody了。

标签: http go response


【解决方案1】:

根据Not_a_GolferJimB 的建议:

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

【讨论】:

    【解决方案2】:

    在上面的答案的基础上,我发现为了让客户将响应视为真正的文章,它需要更完整地形成。对于正常 (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),
    }
    

    然后,例如,您可以添加标题(例如,使用 401 状态代码请求授权)。 req 是您为其生成响应的 http.Request

    【讨论】:

      【解决方案3】:

      这应该可行..

      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!`)
      }
      

      【讨论】:

      • 恕我直言,这是最简单的答案。
      【解决方案4】:

      是的,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)
      

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

      【讨论】:

        猜你喜欢
        • 2011-06-02
        • 2011-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        相关资源
        最近更新 更多