diff --git a/README.md b/README.md index 783ac6b..ee6aa15 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ func main() { Build() response := mock.NewResponseBuilder(http.StatusOK).AddBody(`{"status": "OK"}`).Build() - + mockDefinition := mock.NewDefinition(request, response) err = instance.AddMock(mockDefinition) @@ -92,6 +92,25 @@ response := mock.NewResponseBuilder(http.StatusOK). mockDefinition := mock.NewDefinition(request, response) ``` +You can also include a limit on how many times a mock can be called using the `WithCallLimit` option function. + +```go +request := mock.NewRequestBuilder(http.MethodPut, "/foo/bar"). +AddQueryParam("limit", "10"). +AddQueryParam("filters", "red", "green"). +AddHeader("Content-Type", "application/json", "application/vnd.api+json"). +AddBearerAuthToken("sv2361fr1o8ph3oin"). +AddJsonBody(`{"example": "body"`). +Build() + +response := mock.NewResponseBuilder(http.StatusOK). +AddBody(`{"status": "OK"}`). +AddHeader("Content-Type", "application/json"). +Build() + +mockDefinition := mock.NewDefinition(request, response, mock.WithCallLimit(3)) +``` + ### Raw Json Not all features of the Smocker mocks have been captured in the builders and new features may be added in the future. To diff --git a/mock/context.go b/mock/context.go new file mode 100644 index 0000000..b89edf0 --- /dev/null +++ b/mock/context.go @@ -0,0 +1,13 @@ +package mock + +type ContextOption func(context *Context) *Context + +func WithCallLimit(times int) ContextOption { + return func(context *Context) *Context { + if context == nil { + context = &Context{} + } + context.Times = times + return context + } +} diff --git a/mock/context_test.go b/mock/context_test.go new file mode 100644 index 0000000..67d84fc --- /dev/null +++ b/mock/context_test.go @@ -0,0 +1,35 @@ +package mock_test + +import ( + "github.com/churmd/smockerclient/mock" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestWithCallLimit(t *testing.T) { + t.Run("it creates a new context with the times key if one doesnt exist", func(t *testing.T) { + req := createRequest() + res := createResponse() + def := mock.NewDefinition(req, res, mock.WithCallLimit(3)) + + expectedDef := mock.Definition{ + Request: req, + Response: res, + Context: &mock.Context{Times: 3}, + } + assert.Equal(t, expectedDef, def) + }) + + t.Run("if a context already exists, it uses that", func(t *testing.T) { + req := createRequest() + res := createResponse() + def := mock.NewDefinition(req, res, mock.WithCallLimit(3), mock.WithCallLimit(5)) + + expectedDef := mock.Definition{ + Request: req, + Response: res, + Context: &mock.Context{Times: 5}, + } + assert.Equal(t, expectedDef, def) + }) +} diff --git a/mock/definition.go b/mock/definition.go index 952ca0c..dd9a024 100644 --- a/mock/definition.go +++ b/mock/definition.go @@ -21,16 +21,32 @@ type Response struct { Body string `json:"body,omitempty"` } +type Context struct { + Times int `json:"times"` +} + type Definition struct { Request Request `json:"request"` Response Response `json:"response"` + Context *Context `json:"context,omitempty"` } -func NewDefinition(req Request, resp Response) Definition { - return Definition{ +func NewDefinition(req Request, resp Response, contextOptions ...ContextOption) Definition { + def := Definition{ Request: req, Response: resp, } + + var context *Context + for _, fn := range contextOptions { + context = fn(context) + } + + if context != nil { + def.Context = context + } + + return def } func (d Definition) ToMockDefinitionJson() ([]byte, error) { diff --git a/mock/definition_test.go b/mock/definition_test.go index 87cd1ca..6b5c986 100644 --- a/mock/definition_test.go +++ b/mock/definition_test.go @@ -1,16 +1,16 @@ package mock_test import ( + "github.com/stretchr/testify/assert" "net/http" "testing" - "github.com/stretchr/testify/assert" - "github.com/churmd/smockerclient/mock" ) func TestDefinition_ToMockJson(t *testing.T) { - expectedJson := `{ + t.Run("With no Context", func(t *testing.T) { + expectedJson := `{ "request": { "method": "PUT", "path": "/foo/bar", @@ -36,14 +36,56 @@ func TestDefinition_ToMockJson(t *testing.T) { } }` - request := createRequest() - response := createResponse() - definition := mock.NewDefinition(request, response) + request := createRequest() + response := createResponse() + definition := mock.NewDefinition(request, response) + + actualJson, err := definition.ToMockDefinitionJson() + + assert.NoError(t, err) + assert.JSONEq(t, expectedJson, string(actualJson)) + }) + + t.Run("With Context", func(t *testing.T) { + expectedJson := `{ + "request": { + "method": "PUT", + "path": "/foo/bar", + "query_params": { + "limit": ["10"], + "filters": ["red", "green"] + }, + "headers": { + "Content-Type": ["application/json", "application/vnd.api+json"], + "Authorization": ["Bearer sv2361fr1o8ph3oin"] + }, + "body": { + "matcher": "ShouldEqualJSON", + "value": "{\"name\": \"John Smith\", \"uuid\": \"daa7b90d-9429-4d7a-9304-edc41ff44a6d\", \"rank\": 10}" + } + }, + "context": { + "times": 3 + }, + "response": { + "status": 200, + "headers": { + "Content-Type": ["application/json"] + }, + "body": "{\"status\": \"OK\"}" + } + }` + + request := createRequest() + response := createResponse() + definition := mock.NewDefinition(request, response, mock.WithCallLimit(3)) + + actualJson, err := definition.ToMockDefinitionJson() - actualJson, err := definition.ToMockDefinitionJson() + assert.NoError(t, err) + assert.JSONEq(t, expectedJson, string(actualJson)) + }) - assert.NoError(t, err) - assert.JSONEq(t, expectedJson, string(actualJson)) } func createRequest() mock.Request {