Create http.Response instance with sample body string in golang
Solution 1
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 ioutil.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/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)
}
To play with the code, click here.
Solution 2
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.
Solution 3
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!`)
}
Solution 4
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).
Comments
-
Rana about 4 years
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.