Mock not working
Vindusha opened this issue · 5 comments
I have my http client using transport : [ client := &http.Client{Transport: tr} ]. When I do a mock on this, it fails. Whereas if I remove the transport [ client := &http.Client{} ], it works. Could you please explain a solution to this issue ?
Hi, could you provide a simple test file so we can reproduce your problem?
import (
"crypto/tls"
"encoding/json"
"io/ioutil"
"net/http"
"testing"
"github.com/jarcoal/httpmock"
"github.com/pkg/errors"
)
var trs = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
func RequestDetails() (request string, err error) {
client := &http.Client{Transport: trs}
req, err := http.NewRequest("http://localhost:8080/request", "GET", nil)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
err = json.Unmarshal([]byte(body), &request)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
return request, nil
}
func TestRequestDetails(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("GET", "/request",
httpmock.NewStringResponder(200, `{"key1":"value1"}`))
res, _ := RequestDetails()
if res != "" {
t.Logf("Success")
} else {
t.Errorf("Failure")
}
}
This is my test file. And the test always fails.
As explained in httpmock.Activate
doc:
Under the hood this replaces the Transport on the http.DefaultClient with httpmock.DefaultTransport.
In your test, you don't use http.DefaultClient neither httpmock.DefaultTransport, so the mock is not effective.
changing your trs
definition to:
var trs http.RoundTripper = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
then doing in TestRequestDetails()
, before calling RequestDetails()
:
trs = httpmock.DefaultTransport
should do the work.
var trs http.RoundTripper = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
func RequestDetails() (request string, err error) {
client := &http.Client{Transport: trs}
req, err := http.NewRequest("http://localhost:8080/request", "GET", nil)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
err = json.Unmarshal([]byte(body), &request)
if err != nil {
return request, errors.Wrap(err, "Request Not Found")
}
return request, nil
}
func TestRequestDetails(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
trs = httpmock.DefaultTransport
httpmock.RegisterResponder("GET", "/request",
httpmock.NewStringResponder(200, `{"key1":"value1"}`))
res, _ := RequestDetails()
if res != "" {
t.Logf("Success")
} else {
t.Errorf("Failure")
}
}
I made the following changes. But still it fails.
Your code is full of bugs not related to httpmock:
- bad use of http.NewRequest
- you can't json.Unmarshal a JSON map in a string
read the error your function RequestDetails()
returns, otherwise no need to return an error.