Last active
June 23, 2024 15:37
-
-
Save oleg-schelkunov/7d04f5df0c8ff59b32c6fd6297681493 to your computer and use it in GitHub Desktop.
Examples of HTTP mocks in Golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dummy | |
import ( | |
"fmt" | |
"github.com/go-resty/resty/v2" | |
) | |
type XMLDummy struct { | |
Name string `xml:"Name"` | |
} | |
type JSONDummy struct { | |
Name string `json:"name"` | |
} | |
type DummyService struct { | |
Client *resty.Client | |
} | |
func (s *DummyService) GetXML(url string) (*XMLDummy, error) { | |
r, err := s.Client.R(). | |
SetResult(&XMLDummy{}). | |
Get(url) | |
if err != nil { | |
return nil, err | |
} | |
if !r.IsSuccess() { | |
return nil, fmt.Errorf("request faild with code %d", r.StatusCode()) | |
} | |
return r.Result().(*XMLDummy), nil | |
} | |
func (s *DummyService) GetJSON(url string) (*JSONDummy, error) { | |
r, err := s.Client.R(). | |
SetResult(&JSONDummy{}). | |
Get(url) | |
if err != nil { | |
return nil, err | |
} | |
if !r.IsSuccess() { | |
return nil, fmt.Errorf("request faild with code %d", r.StatusCode()) | |
} | |
return r.Result().(*JSONDummy), nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dummy | |
import ( | |
"errors" | |
"io/ioutil" | |
"net/http" | |
"testing" | |
"github.com/go-resty/resty/v2" | |
"github.com/jarcoal/httpmock" | |
"github.com/stretchr/testify/assert" | |
) | |
func Test_XMLDummy(t *testing.T) { | |
tests := map[string]struct { | |
data string | |
path string | |
respCode int | |
want *XMLDummy | |
wantErr error | |
}{ | |
"happy path": { | |
data: `<root><Name>Oleg</Name></root>`, | |
path: "https://example.com/mynameis", | |
respCode: 200, | |
want: &XMLDummy{Name: "Oleg"}, | |
wantErr: nil, | |
}, | |
} | |
for name, tt := range tests { | |
t.Run(name, func(t *testing.T) { | |
defer httpmock.DeactivateAndReset() | |
rst := resty.New() | |
s := &DummyService{ | |
Client: rst, | |
} | |
httpmock.Activate() | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
httpmock.RegisterResponder("GET", tt.path, newResponder(tt.respCode, tt.data, "application/xml")) | |
got, err := s.GetXML(tt.path) | |
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) { | |
t.Errorf("GetXML() error = %v, wantErr %v", err, tt.wantErr) | |
return | |
} | |
assert.Equal(t, tt.want, got) | |
}) | |
} | |
} | |
func Test_XMLDummyError(t *testing.T) { | |
tests := map[string]struct { | |
data string | |
path string | |
respCode int | |
want *XMLDummy | |
wantErr bool | |
}{ | |
"error response": { | |
data: ``, | |
path: "https://example.com/mynameis", | |
respCode: 500, | |
want: nil, | |
wantErr: true, | |
}, | |
} | |
for name, tt := range tests { | |
t.Run(name, func(t *testing.T) { | |
defer httpmock.DeactivateAndReset() | |
rst := resty.New() | |
s := &DummyService{ | |
Client: rst, | |
} | |
httpmock.Activate() | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
httpmock.RegisterResponder("GET", tt.path, newResponder(tt.respCode, tt.data, "application/xml")) | |
got, err := s.GetXML(tt.path) | |
if (err != nil) != tt.wantErr { | |
t.Errorf("GetXML() error = %v, wantErr %v", err, tt.wantErr) | |
return | |
} | |
assert.Equal(t, tt.want, got) | |
}) | |
} | |
} | |
func Test_JSONDummy(t *testing.T) { | |
tests := map[string]struct { | |
data string | |
path string | |
respCode int | |
want *JSONDummy | |
wantErr error | |
}{ | |
"happy path": { | |
data: `{"name":"Oleg"}`, | |
path: "https://example.com/mynameis", | |
respCode: 200, | |
want: &JSONDummy{Name: "Oleg"}, | |
wantErr: nil, | |
}, | |
} | |
for name, tt := range tests { | |
t.Run(name, func(t *testing.T) { | |
defer httpmock.DeactivateAndReset() | |
rst := resty.New() | |
s := &DummyService{ | |
Client: rst, | |
} | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
httpmock.RegisterResponder("GET", tt.path, newResponder(tt.respCode, tt.data, "application/json")) | |
got, err := s.GetJSON(tt.path) | |
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) { | |
t.Errorf("GetJSON() error = %v, wantErr %v", err, tt.wantErr) | |
return | |
} | |
assert.Equal(t, tt.want, got) | |
}) | |
} | |
} | |
func Test_JSONDummyStringResponder(t *testing.T) { | |
// this test is skipped since it's inteded to fail | |
t.SkipNow() | |
tests := map[string]struct { | |
data string | |
path string | |
respCode int | |
want *JSONDummy | |
wantErr error | |
}{ | |
"happy path": { | |
data: `{"name":"Oleg"}`, | |
path: "https://example.com/mynameis", | |
respCode: 200, | |
want: &JSONDummy{Name: "Oleg"}, | |
wantErr: nil, | |
}, | |
} | |
for name, tt := range tests { | |
t.Run(name, func(t *testing.T) { | |
defer httpmock.DeactivateAndReset() | |
rst := resty.New() | |
s := &DummyService{ | |
Client: rst, | |
} | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
httpmock.RegisterResponder("GET", tt.path, httpmock.NewStringResponder(tt.respCode, tt.data)) | |
got, err := s.GetJSON(tt.path) | |
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) { | |
t.Errorf("GetJSON() error = %v, wantErr %v", err, tt.wantErr) | |
return | |
} | |
assert.Equal(t, tt.want, got) | |
}) | |
} | |
} | |
func Test_JSONDummyJsonResponder(t *testing.T) { | |
tests := map[string]struct { | |
data string | |
path string | |
respCode int | |
want *JSONDummy | |
wantErr error | |
}{ | |
"happy path": { | |
data: `{"name":"Oleg"}`, | |
path: "https://example.com/mynameis", | |
respCode: 200, | |
want: &JSONDummy{Name: "Oleg"}, | |
wantErr: nil, | |
}, | |
} | |
for name, tt := range tests { | |
t.Run(name, func(t *testing.T) { | |
defer httpmock.DeactivateAndReset() | |
rst := resty.New() | |
s := &DummyService{ | |
Client: rst, | |
} | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
httpmock.RegisterResponder("GET", tt.path, httpmock.NewJsonResponderOrPanic(tt.respCode, &JSONDummy{Name: "Oleg"})) | |
got, err := s.GetJSON(tt.path) | |
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) { | |
t.Errorf("GetJSON() error = %v, wantErr %v", err, tt.wantErr) | |
return | |
} | |
assert.Equal(t, tt.want, got) | |
}) | |
} | |
} | |
func Test_MininalCase(t *testing.T) { | |
httpmock.Activate() | |
defer httpmock.DeactivateAndReset() | |
httpmock.RegisterResponder("GET", "https://example.com", httpmock.NewStringResponder(200, "resp string")) | |
resp, _ := http.Get("https://example.com") | |
defer resp.Body.Close() | |
body, _ := ioutil.ReadAll(resp.Body) | |
assert.Equal(t, "resp string", string(body)) | |
} | |
func Test_MininalResty(t *testing.T) { | |
rst := resty.New() | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
defer httpmock.DeactivateAndReset() | |
httpmock.RegisterResponder("GET", "https://example.com", httpmock.NewStringResponder(200, "resp string")) | |
resp, _ := rst.R().Get("https://example.com") | |
assert.Equal(t, "resp string", resp.String()) | |
} | |
func Test_MininalCustomJSON(t *testing.T) { | |
rst := resty.New() | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
defer httpmock.DeactivateAndReset() | |
httpmock.RegisterResponder( | |
"GET", | |
"https://example.com", | |
newResponder(200, `{"name":"Oleg"}`, "application/json"), | |
) | |
resp, _ := rst.R(). | |
SetResult(&JSONDummy{}). | |
Get("https://example.com") | |
assert.Equal(t, &JSONDummy{Name: "Oleg"}, resp.Result().(*JSONDummy)) | |
} | |
func Test_MininalCustomXML(t *testing.T) { | |
rst := resty.New() | |
httpmock.ActivateNonDefault(rst.GetClient()) | |
defer httpmock.DeactivateAndReset() | |
httpmock.RegisterResponder( | |
"GET", | |
"https://example.com", | |
newResponder( | |
200, | |
`<root><Name>Oleg</Name></root>`, | |
"application/xml", | |
), | |
) | |
resp, _ := rst.R(). | |
SetResult(&XMLDummy{}). | |
Get("https://example.com") | |
assert.Equal(t, &XMLDummy{Name: "Oleg"}, resp.Result().(*XMLDummy)) | |
} | |
func newResponder(s int, c string, ct string) httpmock.Responder { | |
resp := httpmock.NewStringResponse(s, c) | |
resp.Header.Set("Content-Type", ct) | |
return httpmock.ResponderFromResponse(resp) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment