From d991c5bfc83b4c01b2a0265d9fb3c65796e522ed Mon Sep 17 00:00:00 2001 From: Valentine Bott Date: Wed, 24 Apr 2024 15:55:25 +0100 Subject: [PATCH 1/5] Adds Context to mock definitions to avoid having to use a raw json definition when requiring Context --- README.md | 27 +++++++++++++++-- examples/createmock.go | 4 ++- mock/context.go | 5 ++++ mock/context_test.go | 15 ++++++++++ mock/definition.go | 15 ++++++++-- mock/definition_test.go | 65 +++++++++++++++++++++++++++++++++++------ 6 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 mock/context.go create mode 100644 mock/context_test.go diff --git a/README.md b/README.md index 783ac6b..9264663 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,10 @@ func main() { Build() response := mock.NewResponseBuilder(http.StatusOK).AddBody(`{"status": "OK"}`).Build() + + limit := mock.NewMockCallLimit(3) - mockDefinition := mock.NewDefinition(request, response) + mockDefinition := mock.NewDefinition(request, response, limit) err = instance.AddMock(mockDefinition) if err != nil { @@ -89,7 +91,28 @@ response := mock.NewResponseBuilder(http.StatusOK). AddHeader("Content-Type", "application/json"). Build() -mockDefinition := mock.NewDefinition(request, response) +mockDefinition := mock.NewDefinition(request, response, nil) +``` + +You can also include a limit on how many times a mock can be called using the `NewMockCallLimit` 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() + +limit := mock.NewMockCallLimit(5) + +mockDefinition := mock.NewDefinition(request, response, limit) ``` ### Raw Json diff --git a/examples/createmock.go b/examples/createmock.go index a39fd0b..02a0bce 100644 --- a/examples/createmock.go +++ b/examples/createmock.go @@ -30,7 +30,9 @@ func main() { response := mock.NewResponseBuilder(http.StatusOK).AddBody(`{"status": "OK"}`).Build() - mockDefinition := mock.NewDefinition(request, response) + limit := mock.NewMockCallLimit(3) + + mockDefinition := mock.NewDefinition(request, response, limit) err = instance.AddMock(mockDefinition) if err != nil { diff --git a/mock/context.go b/mock/context.go new file mode 100644 index 0000000..098d568 --- /dev/null +++ b/mock/context.go @@ -0,0 +1,5 @@ +package mock + +func NewMockCallLimit(t int) *Context { + return &Context{Times: t} +} diff --git a/mock/context_test.go b/mock/context_test.go new file mode 100644 index 0000000..b4db282 --- /dev/null +++ b/mock/context_test.go @@ -0,0 +1,15 @@ +package mock_test + +import ( + "github.com/churmd/smockerclient/mock" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestNewMockCallLimit(t *testing.T) { + expectedContext := &mock.Context{Times: 3} + + actualContext := mock.NewMockCallLimit(3) + + assert.Equal(t, expectedContext, actualContext) +} diff --git a/mock/definition.go b/mock/definition.go index 952ca0c..057b0f0 100644 --- a/mock/definition.go +++ b/mock/definition.go @@ -21,16 +21,27 @@ 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, context *Context) Definition { + def := Definition{ Request: req, Response: resp, } + + 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..d31d343 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,57 @@ func TestDefinition_ToMockJson(t *testing.T) { } }` - request := createRequest() - response := createResponse() - definition := mock.NewDefinition(request, response) + request := createRequest() + response := createResponse() + definition := mock.NewDefinition(request, response, nil) - actualJson, err := definition.ToMockDefinitionJson() + 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() + context := createContext() + definition := mock.NewDefinition(request, response, context) + + 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 { @@ -79,3 +122,7 @@ func createResponse() mock.Response { } return response } + +func createContext() *mock.Context { + return &mock.Context{Times: 3} +} From 42d4a823e417119e8c00cf7d48bc1e3a5560547e Mon Sep 17 00:00:00 2001 From: Valentine Bott Date: Mon, 29 Apr 2024 21:00:29 +0100 Subject: [PATCH 2/5] Switches context for functional options pattern --- mock/context.go | 12 ++++++++++-- mock/context_test.go | 26 +++++++++++++------------- mock/definition.go | 9 +++++++-- mock/definition_test.go | 9 ++------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/mock/context.go b/mock/context.go index 098d568..b89edf0 100644 --- a/mock/context.go +++ b/mock/context.go @@ -1,5 +1,13 @@ package mock -func NewMockCallLimit(t int) *Context { - return &Context{Times: t} +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 index b4db282..4eb4e05 100644 --- a/mock/context_test.go +++ b/mock/context_test.go @@ -1,15 +1,15 @@ package mock_test -import ( - "github.com/churmd/smockerclient/mock" - "github.com/stretchr/testify/assert" - "testing" -) - -func TestNewMockCallLimit(t *testing.T) { - expectedContext := &mock.Context{Times: 3} - - actualContext := mock.NewMockCallLimit(3) - - assert.Equal(t, expectedContext, actualContext) -} +//func TestWithMockCallLimit(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) +//} diff --git a/mock/definition.go b/mock/definition.go index 057b0f0..982a702 100644 --- a/mock/definition.go +++ b/mock/definition.go @@ -22,7 +22,7 @@ type Response struct { } type Context struct { - Times int `json:"times"` + Times int `json:"times,omitempty"` } type Definition struct { @@ -31,12 +31,17 @@ type Definition struct { Context *Context `json:"context,omitempty"` } -func NewDefinition(req Request, resp Response, context *Context) 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 } diff --git a/mock/definition_test.go b/mock/definition_test.go index d31d343..6b5c986 100644 --- a/mock/definition_test.go +++ b/mock/definition_test.go @@ -38,7 +38,7 @@ func TestDefinition_ToMockJson(t *testing.T) { request := createRequest() response := createResponse() - definition := mock.NewDefinition(request, response, nil) + definition := mock.NewDefinition(request, response) actualJson, err := definition.ToMockDefinitionJson() @@ -78,8 +78,7 @@ func TestDefinition_ToMockJson(t *testing.T) { request := createRequest() response := createResponse() - context := createContext() - definition := mock.NewDefinition(request, response, context) + definition := mock.NewDefinition(request, response, mock.WithCallLimit(3)) actualJson, err := definition.ToMockDefinitionJson() @@ -122,7 +121,3 @@ func createResponse() mock.Response { } return response } - -func createContext() *mock.Context { - return &mock.Context{Times: 3} -} From 1b560e6b6238fe21ce3892c34ded638ddb65f699 Mon Sep 17 00:00:00 2001 From: Valentine Bott Date: Tue, 30 Apr 2024 12:31:21 +0100 Subject: [PATCH 3/5] Cleans up test and README --- README.md | 12 ++++-------- examples/createmock.go | 4 +--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9264663..ee6aa15 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,7 @@ func main() { response := mock.NewResponseBuilder(http.StatusOK).AddBody(`{"status": "OK"}`).Build() - limit := mock.NewMockCallLimit(3) - - mockDefinition := mock.NewDefinition(request, response, limit) + mockDefinition := mock.NewDefinition(request, response) err = instance.AddMock(mockDefinition) if err != nil { @@ -91,10 +89,10 @@ response := mock.NewResponseBuilder(http.StatusOK). AddHeader("Content-Type", "application/json"). Build() -mockDefinition := mock.NewDefinition(request, response, nil) +mockDefinition := mock.NewDefinition(request, response) ``` -You can also include a limit on how many times a mock can be called using the `NewMockCallLimit` function. +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"). @@ -110,9 +108,7 @@ AddBody(`{"status": "OK"}`). AddHeader("Content-Type", "application/json"). Build() -limit := mock.NewMockCallLimit(5) - -mockDefinition := mock.NewDefinition(request, response, limit) +mockDefinition := mock.NewDefinition(request, response, mock.WithCallLimit(3)) ``` ### Raw Json diff --git a/examples/createmock.go b/examples/createmock.go index 02a0bce..a39fd0b 100644 --- a/examples/createmock.go +++ b/examples/createmock.go @@ -30,9 +30,7 @@ func main() { response := mock.NewResponseBuilder(http.StatusOK).AddBody(`{"status": "OK"}`).Build() - limit := mock.NewMockCallLimit(3) - - mockDefinition := mock.NewDefinition(request, response, limit) + mockDefinition := mock.NewDefinition(request, response) err = instance.AddMock(mockDefinition) if err != nil { From 8b731661ff9de58ea1bef60243b7a94d0468a12e Mon Sep 17 00:00:00 2001 From: Valentine Bott Date: Tue, 30 Apr 2024 12:34:46 +0100 Subject: [PATCH 4/5] adds unit tests for call limit --- mock/context_test.go | 46 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/mock/context_test.go b/mock/context_test.go index 4eb4e05..67d84fc 100644 --- a/mock/context_test.go +++ b/mock/context_test.go @@ -1,15 +1,35 @@ package mock_test -//func TestWithMockCallLimit(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) -//} +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) + }) +} From 4fd8b4fd65989a527d0883fd88bff857c3996dc8 Mon Sep 17 00:00:00 2001 From: Valentine Bott Date: Tue, 30 Apr 2024 12:35:36 +0100 Subject: [PATCH 5/5] removes unneeded omitempty --- mock/definition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/definition.go b/mock/definition.go index 982a702..dd9a024 100644 --- a/mock/definition.go +++ b/mock/definition.go @@ -22,7 +22,7 @@ type Response struct { } type Context struct { - Times int `json:"times,omitempty"` + Times int `json:"times"` } type Definition struct {