diff --git a/builder.go b/builder.go index cbe1a45..e5f9956 100644 --- a/builder.go +++ b/builder.go @@ -233,13 +233,13 @@ func (b *MockBuilder) PostAction(action core.PostAction) *MockBuilder { } // Reply defines a response mock to be served if this mock matches to a request. -func (b *MockBuilder) Reply(rep core.Reply) *MockBuilder { +func (b *MockBuilder) Reply(rep reply.Reply) *MockBuilder { b.mock.Reply = rep return b } // ReplyFunction defines a function to will build the response mock. -func (b *MockBuilder) ReplyFunction(fn func(*http.Request, *core.Mock, parameters.Params) (*core.Response, error)) *MockBuilder { +func (b *MockBuilder) ReplyFunction(fn func(*http.Request, reply.M, parameters.Params) (*reply.Response, error)) *MockBuilder { b.mock.Reply = reply.Function(fn) return b } diff --git a/core/mock.go b/core/mock.go index 40fdd1a..b51076d 100644 --- a/core/mock.go +++ b/core/mock.go @@ -2,14 +2,13 @@ package core import ( "fmt" - "io" "net/http" "sync" - "time" "github.com/vitorsalgado/mocha/expect" "github.com/vitorsalgado/mocha/internal/autoid" "github.com/vitorsalgado/mocha/internal/parameters" + "github.com/vitorsalgado/mocha/reply" ) type ( @@ -34,10 +33,7 @@ type ( // Reply is the responder that will be used to serve the HTTP response stub, once matched against an // HTTP request. - Reply Reply - - // Hits holds the amount of time this Mock was called and served. - Hits int + Reply reply.Reply // Enabled indicates if the Mock is enabled or disabled. Only enabled mocks are matched. Enabled bool @@ -45,13 +41,14 @@ type ( // PostActions holds PostAction list to be executed after the Mock was matched and served. PostActions []PostAction - mu *sync.Mutex + mu *sync.Mutex + hits int } // PostActionArgs represents the arguments that will be passed to every PostAction implementation PostActionArgs struct { Request *http.Request - Response *Response + Response *reply.Response Mock *Mock Params parameters.Params } @@ -62,31 +59,6 @@ type ( Run(args PostActionArgs) error } - // Response defines the HTTP response that will be served once a Mock is matched for an HTTP Request. - Response struct { - Status int - Header http.Header - Cookies []*http.Cookie - Body io.Reader - Delay time.Duration - Mappers []ResponseMapper - } - - // Reply defines the contract to configure an HTTP responder. - Reply interface { - // Build returns a Response stub to be served. - Build(*http.Request, *Mock, parameters.Params) (*Response, error) - } - - // ResponseMapperArgs represents the expected arguments for every ResponseMapper. - ResponseMapperArgs struct { - Request *http.Request - Parameters parameters.Params - } - - // ResponseMapper is the function definition to be used to map Mock Response before serving it. - ResponseMapper func(res *Response, args ResponseMapperArgs) error - // Weight helps to detect the closest mock match. Weight int @@ -159,19 +131,24 @@ func NewMock() *Mock { func (m *Mock) Hit() { m.mu.Lock() defer m.mu.Unlock() - m.Hits++ + m.hits++ +} + +// Hits returns the amount of time this Mock was matched to a request and served. +func (m *Mock) Hits() int { + return m.hits } // Dec reduce one Mock call. func (m *Mock) Dec() { m.mu.Lock() defer m.mu.Unlock() - m.Hits-- + m.hits-- } // Called checks if the Mock was called at least once. func (m *Mock) Called() bool { - return m.Hits > 0 + return m.hits > 0 } // Enable enables the Mock. diff --git a/core/mock_test.go b/core/mock_test.go index 6c172cc..6d7632c 100644 --- a/core/mock_test.go +++ b/core/mock_test.go @@ -37,7 +37,7 @@ func TestRace(t *testing.T) { wg.Wait() - assert.Equal(t, (jobs*2)+2, m.Hits) + assert.Equal(t, (jobs*2)+2, m.hits) } func TestMock(t *testing.T) { diff --git a/http_handler.go b/http_handler.go index 0405ca2..b3c5f50 100644 --- a/http_handler.go +++ b/http_handler.go @@ -13,6 +13,7 @@ import ( "github.com/vitorsalgado/mocha/internal/headers" "github.com/vitorsalgado/mocha/internal/mimetypes" "github.com/vitorsalgado/mocha/internal/parameters" + "github.com/vitorsalgado/mocha/reply" ) type mockHandler struct { @@ -84,7 +85,7 @@ func (h *mockHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } // map the response using mock mappers. - mapperArgs := core.ResponseMapperArgs{Request: r, Parameters: h.params} + mapperArgs := reply.ResponseMapperArgs{Request: r, Parameters: h.params} for _, mapper := range res.Mappers { if err = mapper(res, mapperArgs); err != nil { respondError(w, r, h.evt, err) diff --git a/mocha_test.go b/mocha_test.go index 5fa7e36..9bdbbff 100644 --- a/mocha_test.go +++ b/mocha_test.go @@ -12,7 +12,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/expect" "github.com/vitorsalgado/mocha/hooks" "github.com/vitorsalgado/mocha/internal/parameters" @@ -111,7 +110,7 @@ func TestResponseMapper(t *testing.T) { scoped := m.AddMocks(Get(expect.URLPath("/test")). Reply(reply. OK(). - Map(func(r *core.Response, rma core.ResponseMapperArgs) error { + Map(func(r *reply.Response, rma reply.ResponseMapperArgs) error { r.Header.Add("x-test", rma.Request.Header.Get("x-param")) return nil }))) @@ -192,7 +191,7 @@ func TestErrors(t *testing.T) { t.Run("should log errors on reply", func(t *testing.T) { scoped := m.AddMocks(Get(expect.URLPath("/test1")). - ReplyFunction(func(r *http.Request, m *core.Mock, p parameters.Params) (*core.Response, error) { + ReplyFunction(func(r *http.Request, m reply.M, p parameters.Params) (*reply.Response, error) { return nil, fmt.Errorf("failed to build a response") })) diff --git a/notifier_test.go b/notifier_test.go index 8594dcb..4cbc157 100644 --- a/notifier_test.go +++ b/notifier_test.go @@ -18,7 +18,5 @@ func TestNotifier_FailNow(t *testing.T) { func TestNotifier_Errorf(t *testing.T) { n := NewStdoutNotifier() - assert.NotPanics(t, func() { - n.Errorf("test %s", "hello") - }) + n.Errorf("test %s", "hello") } diff --git a/reply/func.go b/reply/func.go index a2b9125..86ae3e8 100644 --- a/reply/func.go +++ b/reply/func.go @@ -3,21 +3,20 @@ package reply import ( "net/http" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/internal/parameters" ) // FunctionReply represents a reply that will be built using the given function. type FunctionReply struct { - fn func(*http.Request, *core.Mock, parameters.Params) (*core.Response, error) + fn func(*http.Request, M, parameters.Params) (*Response, error) } // Function returns a FunctionReply that builds a response stub using the given function. -func Function(fn func(*http.Request, *core.Mock, parameters.Params) (*core.Response, error)) *FunctionReply { +func Function(fn func(*http.Request, M, parameters.Params) (*Response, error)) *FunctionReply { return &FunctionReply{fn: fn} } // Build builds a response function using previously provided function. -func (f *FunctionReply) Build(r *http.Request, m *core.Mock, p parameters.Params) (*core.Response, error) { +func (f *FunctionReply) Build(r *http.Request, m M, p parameters.Params) (*Response, error) { return f.fn(r, m, p) } diff --git a/reply/func_test.go b/reply/func_test.go index ea26997..f56d51a 100644 --- a/reply/func_test.go +++ b/reply/func_test.go @@ -7,18 +7,18 @@ import ( "github.com/stretchr/testify/assert" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/internal/parameters" ) func TestFunctionReply(t *testing.T) { - fn := func(*http.Request, *core.Mock, parameters.Params) (*core.Response, error) { - return &core.Response{Status: http.StatusAccepted}, nil + fn := func(*http.Request, M, parameters.Params) (*Response, error) { + return &Response{Status: http.StatusAccepted}, nil } req := httptest.NewRequest(http.MethodGet, "http://localhost", nil) replier := Function(fn) - m := core.NewMock() + m := &mmock{} + m.On("Hits").Return(0) res, err := replier.Build(req, m, nil) assert.Nil(t, err) diff --git a/reply/mocks.go b/reply/mocks.go new file mode 100644 index 0000000..2251462 --- /dev/null +++ b/reply/mocks.go @@ -0,0 +1,12 @@ +package reply + +import "github.com/stretchr/testify/mock" + +type mmock struct { + mock.Mock +} + +func (m *mmock) Hits() int { + args := m.Called() + return args.Int(0) +} diff --git a/reply/proxied.go b/reply/proxied.go index 96b2e81..85813aa 100644 --- a/reply/proxied.go +++ b/reply/proxied.go @@ -8,7 +8,6 @@ import ( "strings" "time" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/internal/parameters" ) @@ -88,8 +87,8 @@ func (r *ProxyReply) StripSuffix(suffix string) *ProxyReply { return r } -// Build builds a core.Reply based on the ProxyReply configuration. -func (r *ProxyReply) Build(req *http.Request, _ *core.Mock, _ parameters.Params) (*core.Response, error) { +// Build builds a Reply based on the ProxyReply configuration. +func (r *ProxyReply) Build(req *http.Request, _ M, _ parameters.Params) (*Response, error) { path := req.URL.Path if r.trimPrefix != "" { @@ -122,7 +121,7 @@ func (r *ProxyReply) Build(req *http.Request, _ *core.Mock, _ parameters.Params) return nil, err } - response := &core.Response{ + response := &Response{ Status: res.StatusCode, Header: res.Header, Cookies: res.Cookies(), diff --git a/reply/random.go b/reply/random.go index b109e9e..4783557 100644 --- a/reply/random.go +++ b/reply/random.go @@ -5,26 +5,25 @@ import ( "math/rand" "net/http" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/internal/parameters" ) -// RandomReply configures a core.Reply that serves random HTTP responses. +// RandomReply configures a Reply that serves random HTTP responses. type RandomReply struct { - replies []core.Reply + replies []Reply } // Rand inits a new RandomReply. -func Rand() *RandomReply { return &RandomReply{replies: make([]core.Reply, 0)} } +func Rand() *RandomReply { return &RandomReply{replies: make([]Reply, 0)} } -// Add adds a new core.Reply to the random list. -func (mr *RandomReply) Add(reply ...core.Reply) *RandomReply { +// Add adds a new Reply to the random list. +func (mr *RandomReply) Add(reply ...Reply) *RandomReply { mr.replies = append(mr.replies, reply...) return mr } -// Build builds a response stub randomly based on previously added core.Reply implementations. -func (mr *RandomReply) Build(r *http.Request, m *core.Mock, p parameters.Params) (*core.Response, error) { +// Build builds a response stub randomly based on previously added Reply implementations. +func (mr *RandomReply) Build(r *http.Request, m M, p parameters.Params) (*Response, error) { size := len(mr.replies) if size == 0 { return nil, diff --git a/reply/random_test.go b/reply/random_test.go index 2e4fe34..70464bf 100644 --- a/reply/random_test.go +++ b/reply/random_test.go @@ -5,12 +5,11 @@ import ( "testing" "github.com/stretchr/testify/assert" - - "github.com/vitorsalgado/mocha/core" ) func TestRandomReplies(t *testing.T) { - m := core.Mock{Name: "mock_test"} + m := &mmock{} + req, _ := http.NewRequest(http.MethodGet, "http://localhost:8080", nil) statuses := []int{ http.StatusOK, http.StatusInternalServerError, http.StatusCreated, http.StatusBadRequest} @@ -18,7 +17,7 @@ func TestRandomReplies(t *testing.T) { for i := 0; i < 5000; i++ { res, err := Rand(). Add(BadRequest(), OK(), Created(), InternalServerError()). - Build(req, &m, nil) + Build(req, m, nil) contains := false for _, status := range statuses { diff --git a/reply/reply.go b/reply/reply.go index 5a782eb..00dee69 100644 --- a/reply/reply.go +++ b/reply/reply.go @@ -8,14 +8,25 @@ import ( "strings" "time" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/internal/parameters" ) type ( - // StdReply holds the configuration on how the core.Response should be built. + // M implements mock data that should be available on reply build functions. + M interface { + // Hits return mock total hits. + Hits() int + } + + // Reply defines the contract to configure an HTTP responder. + Reply interface { + // Build returns a Response stub to be served. + Build(*http.Request, M, parameters.Params) (*Response, error) + } + + // StdReply holds the configuration on how the Response should be built. StdReply struct { - response *core.Response + response *Response bodyType bodyType template Template model any @@ -33,88 +44,88 @@ const ( // New creates a new StdReply. Prefer to use factory functions for each status code. func New() *StdReply { return &StdReply{ - response: &core.Response{ + response: &Response{ Cookies: make([]*http.Cookie, 0), Header: make(http.Header), - Mappers: make([]core.ResponseMapper, 0), + Mappers: make([]ResponseMapper, 0), }, bodyType: _bodyDefault, } } -// Status creates a new core.Reply with the given HTTP status code. +// Status creates a new Reply with the given HTTP status code. func Status(status int) *StdReply { return New().Status(status) } -// OK creates a new core.Reply with http.StatusOK already. +// OK creates a new Reply with http.StatusOK already. func OK() *StdReply { return New().Status(http.StatusOK) } -// Created creates a new core.Reply with http.StatusCreated already. +// Created creates a new Reply with http.StatusCreated already. func Created() *StdReply { return New().Status(http.StatusCreated) } -// Accepted creates a new core.Reply with http.StatusAccepted already. +// Accepted creates a new Reply with http.StatusAccepted already. func Accepted() *StdReply { return New().Status(http.StatusAccepted) } -// NoContent creates a new core.Reply with http.StatusNoContent already. +// NoContent creates a new Reply with http.StatusNoContent already. func NoContent() *StdReply { return New().Status(http.StatusNoContent) } -// PartialContent creates a new core.Reply with http.StatusPartialContent already. +// PartialContent creates a new Reply with http.StatusPartialContent already. func PartialContent() *StdReply { return New().Status(http.StatusPartialContent) } -// MovedPermanently creates a new core.Reply with http.StatusMovedPermanently already. +// MovedPermanently creates a new Reply with http.StatusMovedPermanently already. func MovedPermanently() *StdReply { return New().Status(http.StatusMovedPermanently) } -// NotModified creates a new core.Reply with http.StatusNotModified already. +// NotModified creates a new Reply with http.StatusNotModified already. func NotModified() *StdReply { return New().Status(http.StatusNotModified) } -// BadRequest creates a new core.Reply with http.StatusBadRequest already. +// BadRequest creates a new Reply with http.StatusBadRequest already. func BadRequest() *StdReply { return New().Status(http.StatusBadRequest) } -// Unauthorized creates a new core.Reply with http.StatusUnauthorized already. +// Unauthorized creates a new Reply with http.StatusUnauthorized already. func Unauthorized() *StdReply { return New().Status(http.StatusUnauthorized) } -// Forbidden creates a new core.Reply with http.StatusForbidden already. +// Forbidden creates a new Reply with http.StatusForbidden already. func Forbidden() *StdReply { return New().Status(http.StatusForbidden) } -// NotFound creates a new core.Reply with http.StatusNotFound already. +// NotFound creates a new Reply with http.StatusNotFound already. func NotFound() *StdReply { return New().Status(http.StatusNotFound) } -// MethodNotAllowed creates a new core.Reply with http.StatusMethodNotAllowed already. +// MethodNotAllowed creates a new Reply with http.StatusMethodNotAllowed already. func MethodNotAllowed() *StdReply { return New().Status(http.StatusMethodNotAllowed) } -// UnprocessableEntity creates a new core.Reply with http.StatusUnprocessableEntity already. +// UnprocessableEntity creates a new Reply with http.StatusUnprocessableEntity already. func UnprocessableEntity() *StdReply { return New().Status(http.StatusUnprocessableEntity) } -// MultipleChoices creates a new core.Reply with http.StatusMultipleChoices already. +// MultipleChoices creates a new Reply with http.StatusMultipleChoices already. func MultipleChoices() *StdReply { return New().Status(http.StatusMultipleChoices) } -// InternalServerError creates a new core.Reply with http.StatusInternalServerError already. +// InternalServerError creates a new Reply with http.StatusInternalServerError already. func InternalServerError() *StdReply { return New().Status(http.StatusInternalServerError) } -// NotImplemented creates a new core.Reply with http.StatusNotImplemented already. +// NotImplemented creates a new Reply with http.StatusNotImplemented already. func NotImplemented() *StdReply { return New().Status(http.StatusNotImplemented) } -// BadGateway creates a new core.Reply with http.StatusBadGateway already. +// BadGateway creates a new Reply with http.StatusBadGateway already. func BadGateway() *StdReply { return New().Status(http.StatusBadGateway) } -// ServiceUnavailable creates a new core.Reply with http.StatusServiceUnavailable already. +// ServiceUnavailable creates a new Reply with http.StatusServiceUnavailable already. func ServiceUnavailable() *StdReply { return New().Status(http.StatusServiceUnavailable) } -// GatewayTimeout creates a new core.Reply with http.StatusGatewayTimeout already. +// GatewayTimeout creates a new Reply with http.StatusGatewayTimeout already. func GatewayTimeout() *StdReply { return New().Status(http.StatusGatewayTimeout) } -// Status sets the HTTP status code for the core.Response. +// Status sets the HTTP status code for the Response. func (rpl *StdReply) Status(status int) *StdReply { rpl.response.Status = status return rpl } -// Header adds a header to the core.Response. +// Header adds a header to the Response. func (rpl *StdReply) Header(key, value string) *StdReply { rpl.response.Header.Add(key, value) return rpl } -// Cookie adds a http.Cookie to the core.Response. +// Cookie adds a http.Cookie to the Response. func (rpl *StdReply) Cookie(cookie http.Cookie) *StdReply { rpl.response.Cookies = append(rpl.response.Cookies, &cookie) return rpl @@ -184,20 +195,20 @@ func (rpl *StdReply) Model(model any) *StdReply { return rpl } -// Delay sets a delay time before serving the stub core.Response. +// Delay sets a delay time before serving the stub Response. func (rpl *StdReply) Delay(duration time.Duration) *StdReply { rpl.response.Delay = duration return rpl } -// Map adds core.ResponseMapper that will be executed after the core.Response was built. -func (rpl *StdReply) Map(mapper core.ResponseMapper) *StdReply { +// Map adds ResponseMapper that will be executed after the Response was built. +func (rpl *StdReply) Map(mapper ResponseMapper) *StdReply { rpl.response.Mappers = append(rpl.response.Mappers, mapper) return rpl } -// Build builds a core.Response based on StdReply definition. -func (rpl *StdReply) Build(r *http.Request, _ *core.Mock, _ parameters.Params) (*core.Response, error) { +// Build builds a Response based on StdReply definition. +func (rpl *StdReply) Build(r *http.Request, _ M, _ parameters.Params) (*Response, error) { if rpl.err != nil { return nil, rpl.err } diff --git a/reply/reply_test.go b/reply/reply_test.go index 00ea95d..fbb4188 100644 --- a/reply/reply_test.go +++ b/reply/reply_test.go @@ -10,12 +10,10 @@ import ( "time" "github.com/stretchr/testify/assert" - - "github.com/vitorsalgado/mocha/core" ) var ( - testMock = core.Mock{Name: "mock_test"} + testMock = &mmock{} req, _ = http.NewRequest(http.MethodGet, "http://localhost:8080", nil) ) @@ -57,7 +55,7 @@ func TestReply(t *testing.T) { ExpireCookie(http.Cookie{Name: "cookie_test_remove"}). Body([]byte("hi")). Delay(5*time.Second). - Build(req, &testMock, nil) + Build(req, testMock, nil) assert.Nil(t, err) @@ -79,7 +77,7 @@ func TestStdReply_BodyString(t *testing.T) { res, err := New(). Status(http.StatusCreated). BodyString("text"). - Build(req, &testMock, nil) + Build(req, testMock, nil) assert.Nil(t, err) @@ -100,7 +98,7 @@ func TestStdReply_BodyJSON(t *testing.T) { res, err := New(). Status(http.StatusCreated). BodyJSON(model). - Build(req, &testMock, nil) + Build(req, testMock, nil) assert.Nil(t, err) @@ -115,7 +113,7 @@ func TestStdReply_BodyJSON(t *testing.T) { res, err := New(). Status(http.StatusCreated). BodyJSON(make(chan int)). - Build(req, &testMock, nil) + Build(req, testMock, nil) assert.Nil(t, res) assert.NotNil(t, err) @@ -134,7 +132,7 @@ func TestStdReply_BodyReader(t *testing.T) { res, err := New(). Status(http.StatusCreated). BodyReader(f). - Build(req, &testMock, nil) + Build(req, testMock, nil) assert.Nil(t, err) diff --git a/reply/response.go b/reply/response.go new file mode 100644 index 0000000..368d7f2 --- /dev/null +++ b/reply/response.go @@ -0,0 +1,30 @@ +package reply + +import ( + "io" + "net/http" + "time" + + "github.com/vitorsalgado/mocha/internal/parameters" +) + +type ( + // Response defines the HTTP response that will be served once a Mock is matched for an HTTP Request. + Response struct { + Status int + Header http.Header + Cookies []*http.Cookie + Body io.Reader + Delay time.Duration + Mappers []ResponseMapper + } + + // ResponseMapperArgs represents the expected arguments for every ResponseMapper. + ResponseMapperArgs struct { + Request *http.Request + Parameters parameters.Params + } + + // ResponseMapper is the function definition to be used to map Mock Response before serving it. + ResponseMapper func(res *Response, args ResponseMapperArgs) error +) diff --git a/reply/seq.go b/reply/seq.go index ed47067..e09d19b 100644 --- a/reply/seq.go +++ b/reply/seq.go @@ -4,46 +4,46 @@ import ( "fmt" "net/http" - "github.com/vitorsalgado/mocha/core" "github.com/vitorsalgado/mocha/internal/parameters" ) // SequentialReply configures a sequence of replies to be used after a mock.Mock is matched to a http.Request. type SequentialReply struct { - replyOnNotFound core.Reply - replies []core.Reply + replyOnNotFound Reply + replies []Reply } // Seq creates a new SequentialReply. func Seq() *SequentialReply { - return &SequentialReply{replies: make([]core.Reply, 0)} + return &SequentialReply{replies: make([]Reply, 0)} } // AfterEnded sets a response to be used once the sequence is over. -func (mr *SequentialReply) AfterEnded(reply core.Reply) *SequentialReply { +func (mr *SequentialReply) AfterEnded(reply Reply) *SequentialReply { mr.replyOnNotFound = reply return mr } // Add adds a new response to the sequence. -func (mr *SequentialReply) Add(reply ...core.Reply) *SequentialReply { +func (mr *SequentialReply) Add(reply ...Reply) *SequentialReply { mr.replies = append(mr.replies, reply...) return mr } // Build builds a new response based on current mock.Mock call sequence. // When the sequence is over, it will return an error or a previously configured reply for this scenario. -func (mr *SequentialReply) Build(r *http.Request, m *core.Mock, p parameters.Params) (*core.Response, error) { +func (mr *SequentialReply) Build(r *http.Request, m M, p parameters.Params) (*Response, error) { size := len(mr.replies) + hits := m.Hits() if size == 0 { return nil, fmt.Errorf("you need to set at least one response when using multiple response builder") } - var reply core.Reply + var reply Reply - if m.Hits <= size { - reply = mr.replies[m.Hits-1] + if hits <= size { + reply = mr.replies[hits-1] } if reply == nil { @@ -54,7 +54,7 @@ func (mr *SequentialReply) Build(r *http.Request, m *core.Mock, p parameters.Par return nil, fmt.Errorf( "unable to obtain a response and no default response was set. request number: %d - sequence size: %d", - m.Hits, + hits, size) } diff --git a/reply/seq_test.go b/reply/seq_test.go index 86da362..9ea3b4c 100644 --- a/reply/seq_test.go +++ b/reply/seq_test.go @@ -5,55 +5,67 @@ import ( "testing" "github.com/stretchr/testify/assert" - - "github.com/vitorsalgado/mocha/core" ) func TestSequential(t *testing.T) { t.Run("should return replies based configure sequence and return error when over", func(t *testing.T) { - m := core.NewMock() - m.Name = "mock_test" + m := &mmock{} + handler := m.On("Hits").Return(0) req, _ := http.NewRequest(http.MethodGet, "http://localhost:8080", nil) builder := Seq(). Add(InternalServerError(), BadRequest(), OK(), NotFound()) - m.Hit() + handler.Unset() + handler = m.On("Hits").Return(1) + res, err := builder.Build(req, m, nil) assert.Nil(t, err) assert.Equal(t, http.StatusInternalServerError, res.Status) - m.Hit() + handler.Unset() + handler = m.On("Hits").Return(2) + res, err = builder.Build(req, m, nil) assert.Nil(t, err) assert.Equal(t, http.StatusBadRequest, res.Status) - m.Hit() + handler.Unset() + handler = m.On("Hits").Return(3) + res, err = builder.Build(req, m, nil) assert.Nil(t, err) assert.Equal(t, http.StatusOK, res.Status) - m.Hit() + handler.Unset() + handler = m.On("Hits").Return(4) + res, err = builder.Build(req, m, nil) assert.Nil(t, err) assert.Equal(t, http.StatusNotFound, res.Status) - m.Hit() + handler.Unset() + m.On("Hits").Return(5) + _, err = builder.Build(req, m, nil) assert.NotNil(t, err) }) t.Run("should return replies based configure sequence and return error when over", func(t *testing.T) { - m := core.NewMock() - m.Name = "mock_test" + m := &mmock{} + handler := m.On("Hits").Return(0) req, _ := http.NewRequest(http.MethodGet, "http://localhost:8080", nil) builder := Seq().Add(OK()).AfterEnded(NotFound()) - m.Hit() + handler.Unset() + handler = m.On("Hits").Return(1) + res, err := builder.Build(req, m, nil) assert.Nil(t, err) assert.Equal(t, http.StatusOK, res.Status) - m.Hit() + handler.Unset() + m.On("Hits").Return(2) + res, err = builder.Build(req, m, nil) assert.Nil(t, err) assert.Equal(t, http.StatusNotFound, res.Status) @@ -61,7 +73,10 @@ func TestSequential(t *testing.T) { } func TestShouldReturnErrorWhenSequenceDoesNotContainReplies(t *testing.T) { - res, err := Seq().Build(nil, nil, nil) + m := &mmock{} + m.On("Hits").Return(0) + + res, err := Seq().Build(nil, m, nil) assert.Nil(t, res) assert.NotNil(t, err) } diff --git a/reply/template_test.go b/reply/template_test.go index 5007c2c..e59b6fa 100644 --- a/reply/template_test.go +++ b/reply/template_test.go @@ -70,7 +70,7 @@ func TestReplyWithTemplate(t *testing.T) { FuncMap(template.FuncMap{"trim": strings.TrimSpace}). Template(string(b))). Model(data). - Build(req, &testMock, nil) + Build(req, testMock, nil) if err != nil { t.Fatal(err) diff --git a/scoped.go b/scoped.go index 8e93a63..3ad6ba3 100644 --- a/scoped.go +++ b/scoped.go @@ -157,7 +157,7 @@ func (s *Scoped) AssertNotCalled(t core.T) bool { func (s *Scoped) Hits() int { total := 0 for _, m := range s.mocks { - total += m.Hits + total += m.Hits() } return total