英文:
Create http.Response instance with sample body string in golang
问题
我愿意在golang中创建一个带有示例body字符串的http.Response
实例。
问题是,它的body属性接受ReadCloser
实例。但由于它是一个虚拟的响应实例,我想知道是否有一些技巧可以轻松设置它,而不需要设置所有的流读取/关闭部分。
英文:
I am willing to create a sample http.Response
instance in golang with a sample body string.
Problem is, its body property accepts ReadCloser
instance. But as its a dummy response instance, I was wondering if there is some trick to set it easily without setting up all that stream read/close parts.
答案1
得分: 58
根据Not_a_Golfer和JimB的建议:
io.ReadCloser
是一个接口,当一个struct
同时实现了Read
和Close
函数时,它就会被满足。
幸运的是,有一个io.NopCloser
函数,它接受一个io.Reader
并将其包装在nopCloser
结构体中,该结构体同时实现了Read
和Close
函数。然而,根据名称,它的Close
函数什么也不做。
以下是一个示例代码:
package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
t := http.Response{
Body: io.NopCloser(bytes.NewBufferString("Hello World")),
}
buff := bytes.NewBuffer(nil)
t.Write(buff)
fmt.Println(buff)
}
要尝试运行这段代码,请点击这里。
英文:
As suggested by Not_a_Golfer and JimB:
io.ReadCloser
is an interface that is satisfied when a struct
implements both the Read
and the Close
functions.
Fortunately, there is io.NopCloser
, which takes a io.Reader
and wraps it in the nopCloser
struct, which implements both Read
and Close
. However, its Close
function does nothing as implied from the name.
Here is an example:
package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
t := http.Response{
Body: io.NopCloser(bytes.NewBufferString("Hello World")),
}
buff := bytes.NewBuffer(nil)
t.Write(buff)
fmt.Println(buff)
}
To play with the code, click here.
答案2
得分: 23
根据顶部的答案,我发现为了让响应被客户端视为真实的文章,它需要更完整的形式。对于正常的(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
。
英文:
Further to the top answer, I have found that in order for the response to be treated as the genuine article by clients, it needs to be more fully formed. For a normal (200) response, I do the following:
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),
}
Then you can, for example, add headers (with a 401 status code, to ask for authorisation, say). req
is the http.Request
for which you are generating the response.
答案3
得分: 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, `成功!`)
}
英文:
This should work..
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
得分: 2
是的,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)。
英文:
Yes, the ioutil.NopCloser
is just what I needed!
Am trying to test a method that performs calls to the facebook API (via a helper function) for a social-connect endpoint, and I want to mock the facebook response coming from the helper function, so my solution is like follows:
Expected facebook response (converted to my own UserData
struct) is:
UserData {
ID: facebookID,
Email: email,
FirstName: firstName,
LastName: lastName,
}
So I create the expected response like this:
fbUserData, _ := json.Marshal(UserData{
ID: facebookID,
Email: email,
FirstName: firstName,
LastName: lastName,
})
fbUserDataResponse := &http.Response{
Body: ioutil.NopCloser(bytes.NewBufferString(string(fbUserData))),
}
Then I can mock the response for the method calling the facebook API like this:
s.fbGateway.EXPECT().ExecuteGetQuery(userUrl).Return(fbUserDataResponse, nil).Times(1)
The point here is that this is really about mocking any kind of functions that return *http.Response
data (in my case I am calling the facebook API via a helper function that returns the http Response, as mentioned above).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论