I’ve the following function which after help of @poy I was able to create mock for it in order to unit test it.
The issue now that I’ve wrapper function which needs also to be tested
This is the original function which have working test
func httpReq(cc []string, method string, url string) ([]byte, error) {
httpClient := http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to execute http request")
}
//Here we are passing user and password
req.SetBasicAuth(cc[1], cc[2])
res, err := httpClient.Do(req)
if err != nil {
fmt.error(err)
}
val, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.error(err)
}
defer res.Body.Close()
return val, nil
}
This is the test which works as expected, this test use https://golang.org/pkg/net/http/httptest/ in order to mock http requests.
func Test_httpReq(t *testing.T){
expectedValue = "some-value"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
u,p,ok := r.BasicAuth()
if !ok || u != "fakeuser" || p != "fakepassword" {
t.Fatal("wrong auth")
}
w.Write([]byte(expectedValue))
})
val, err := httpReq(
[]string{"fakeuser", "fakepassword"},
http.MethodPost,
server.URL,
)
if err != nil{
t.Fatal(err)
}
if val != expectedValue {
t.Fatalf("expected %q to equal %q", val, expectedValue)
}
Now the issue is that I’ve another function which call to the above function which needs to be tested also.
This is the function which use httpReq and I need to create test also for it
func (c *Service) invoke(Connection Connection, args []string) {
service, err := c.getService(Connection, args)
serviceC, err := c.getServiceK(service, []string{"url", “user”, “id”})
c := strings.Fields(serviceC)
//—————Here we are using the http function again
val, err := httpReq(c[1], c[1],”post”, c[0])
if err != nil {
fmt.println(err)
}
fmt.Print(string(val))
}
Now when I use the test for it I got error inside the http request method since here I cannot mock the http.
Is there any technique
In Golang
Which can help which this kind of scenario?
I've search about it, something like dependency injection and found that maybe interface could help, but since this is http I'm not sure how to do it.
Any example with this context will be very helpful to me.
Service object can have an interface like this
Normal application code can init services with actual objects. Tests will have mocks objects
when you are running tests, you can initialise the service object with mock Implementation that returns a dummy response.
This is one of way testing it. Other way could be I guess where httpReq return http.ResponseWriter and you can use httptest.ResponseRecorder to test it.