If your application uses a HTTP client to call another service and if you wish not to call the service in test environment, you can use example below. It mocks the service so your HTTP client calls mock service instead.


Client


package pkg

import "net/http"

type Consumer struct {
ServiceAddress string
}

func (c Consumer) GetUsers() (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, c.ServiceAddress + "/server/api/v1/users", nil)
if err != nil {
return nil, err
}

client := http.Client{}
res, err := client.Do(req)
if err != nil {
return nil, err
}

return res, nil
}

Test


package pkg

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)

func TestConsumer_GetUsers(t *testing.T) {
srv := serverMock()
defer srv.Close()

consumer := Consumer{ServiceAddress: srv.URL}

res, err := consumer.GetUsers()
if err != nil {
t.Error(err)
}

body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Error(err)
}
res.Body.Close()

if http.StatusOK != res.StatusCode {
t.Error("expected", http.StatusOK, "got", res.StatusCode)
}
if "mock server responding" != string(body) {
t.Error("expected mock server responding got", string(body))
}
}

func serverMock() *httptest.Server {
handler := http.NewServeMux()
handler.HandleFunc("/server/api/v1/users", usersMock)

srv := httptest.NewServer(handler)

return srv
}

func usersMock(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("mock server responding"))
}