Skip to content

Commit

Permalink
support multiple mocks
Browse files Browse the repository at this point in the history
  • Loading branch information
stein committed Jan 15, 2019
1 parent 3479eef commit 43985c5
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 4 deletions.
10 changes: 9 additions & 1 deletion apitest.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ func New(name ...string) *APITest {

// Mocks is a builder method for setting the mocks
func (a *APITest) Mocks(mocks ...*Mock) *APITest {
a.mocks = mocks
var m []*Mock
for i := range mocks {
times := mocks[i].response.times
for j := 1; j <= times; j++ {
mockCopy := *mocks[i]
m = append(m, &mockCopy)
}
}
a.mocks = m
return a
}

Expand Down
26 changes: 24 additions & 2 deletions apitest_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package apitest

import (
"fmt"
"io/ioutil"
"net/http"
"reflect"
Expand Down Expand Up @@ -78,7 +79,6 @@ func TestApiTest_AddsQueryParamCollectionToRequest(t *testing.T) {
})

New().
Observe(DumpHttp).
Handler(handler).
Get("/hello").
QueryCollection(map[string][]string{"a": {"b", "c", "d"}}).
Expand All @@ -99,7 +99,6 @@ func TestApiTest_AddsQueryParamCollectionToRequest_HandlesEmpty(t *testing.T) {
})

New().
Observe(DumpHttp).
Handler(handler).
Get("/hello").
QueryCollection(map[string][]string{}).
Expand Down Expand Up @@ -412,6 +411,29 @@ func TestApiTest_Intercept(t *testing.T) {
End()
}

func TestApiTest_ReplicatesMocks(t *testing.T) {
tests := []struct {
times int
}{
{1}, {15}, {0}, {2},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%v", test.times), func(t *testing.T) {
mock := NewMock().
Get("/abc").
RespondWith().
Status(http.StatusOK).
Times(test.times).
End()

numMocks := len(New().Mocks(mock).mocks)
if numMocks != test.times {
t.Fatalf("expected %d instances of the mock to be defined, but was %d", test.times, numMocks)
}
})
}
}

func TestApiTest_ExposesRequestAndResponse(t *testing.T) {
apiTest := New()

Expand Down
1 change: 0 additions & 1 deletion examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ require (
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/steinfletcher/api-test v0.0.3
github.com/steinfletcher/api-test-jsonpath v0.0.1
github.com/stretchr/testify v1.3.0 // indirect
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 // indirect
golang.org/x/net v0.0.0-20190110200230-915654e7eabc // indirect
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
Expand All @@ -21,6 +22,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/steinfletcher/api-test-jsonpath v0.0.1 h1:kQuZzE6n8HkyvUmw5MDTDOElYueY8crJU+RwjIi7GkA=
github.com/steinfletcher/api-test-jsonpath v0.0.1/go.mod h1:CiTtJEgXWOZ9T4vOfYi3JYdW1GiD5oMLVnigJFJxEV8=
Expand Down
14 changes: 14 additions & 0 deletions mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func buildResponseFromMock(mockResponse *MockResponse) *http.Response {
}

type Mock struct {
isUsed bool
request *MockRequest
response *MockResponse
}
Expand All @@ -98,6 +99,7 @@ type MockResponse struct {
cookies []*Cookie
body string
statusCode int
times int
}

func NewMock() *Mock {
Expand All @@ -110,6 +112,7 @@ func NewMock() *Mock {
res := &MockResponse{
mock: mock,
headers: map[string][]string{},
times: 1,
}
mock.request = req
mock.response = res
Expand Down Expand Up @@ -161,14 +164,20 @@ func (m *Mock) Method(method string) *MockRequest {

func matches(req *http.Request, mocks []*Mock) *MockResponse {
for _, mock := range mocks {
if mock.isUsed {
continue
}

matches := true
for _, matcher := range matchers {
if !matcher(req, mock.request) {
matches = false
break
}
}

if matches {
mock.isUsed = true
return mock.response
}
}
Expand Down Expand Up @@ -245,6 +254,11 @@ func (r *MockResponse) Status(statusCode int) *MockResponse {
return r
}

func (r *MockResponse) Times(times int) *MockResponse {
r.times = times
return r
}

func (r *MockResponse) End() *Mock {
return r.mock
}
Expand Down
47 changes: 47 additions & 0 deletions mocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,53 @@ func TestMocks_ApiTest_WithMocks(t *testing.T) {
}
}

func TestMocks_ApiTest_SupportsMultipleMocks(t *testing.T) {
getUser := NewMock().
Get("http://localhost:8080").
RespondWith().
Status(http.StatusOK).
Body("1").
Times(2).
End()

getPreferences := NewMock().
Get("http://localhost:8080").
RespondWith().
Status(http.StatusOK).
Body("2").
End()

New().
Mocks(getUser, getPreferences).
Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
bytes1 := getUserData()
bytes2 := getUserData()
bytes3 := getUserData()

w.Write(bytes1)
w.Write(bytes2)
w.Write(bytes3)
w.WriteHeader(http.StatusOK)
})).
Get("/").
Expect(t).
Status(http.StatusOK).
Body(`112`).
End()
}

func getUserData() []byte {
res, err := http.Get("http://localhost:8080")
if err != nil {
panic(err)
}
bytes, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
return bytes
}

func getUserHandler(get HttpGet) *http.ServeMux {
handler := http.NewServeMux()
handler.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit 43985c5

Please sign in to comment.