Skip to content

Instantly share code, notes, and snippets.

@oleg-schelkunov
Last active March 8, 2021 08:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oleg-schelkunov/7d04f5df0c8ff59b32c6fd6297681493 to your computer and use it in GitHub Desktop.
Save oleg-schelkunov/7d04f5df0c8ff59b32c6fd6297681493 to your computer and use it in GitHub Desktop.
Examples of HTTP mocks in Golang
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
}
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