I'm trying to test a method that uses net/http
to make requests. Specifically what I'm trying to achieve is to inject a mock http.Client
that responds with a certain JSON body
type clientMock struct{}
func (c *clientMock) Do(req *http.Request) (*http.Response, error) {
json := struct {
AccessToken string `json:"access_token`
Scope string `json:"scope"`
}{
AccessToken: "123457678",
Scope: "read, write",
}
body := json.Marshal(json)
res := &http.Response {
StatusCode: http.StatusOK,
Body: // I haven't got a clue what to put here
}
return res
}
func TestRequest(t *testing.T) { //tests here }
I do know that the Body
is of a type io.ReadCloser
interface. Trouble is I can't for the life of me find a way to implement it in the mock body response.
Examples as found here so far only demonstrates returning a blank &http.Response{}
To return JSON from the server, you must include the JSON data in the body of the HTTP response message and provide a "Content-Type: application/json" response header. The Content-Type response header allows the client to interpret the data in the response body correctly.
Mocking HttpClient is possible although an arduous task. Luckily there is still a great way to unit test the code. The solution is to mock HttpMessageHandler and pass this object to the HttpClient constructor. When we use the message handler to make HTTP requests, we achieve our unit testing goals.
While it's probably more useful to mock the full request cycle with httptest.Server
, you can use ioutil.NopCloser
to create the closer around any reader:
Body: ioutil.NopCloser(bytes.NewReader(body))
and if you want an empty body, just provider a reader with no content.
Body: ioutil.NopCloser(bytes.NewReader(nil))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With