diff --git a/stubs.go b/stubs.go index 8c82ac4..f3c94e0 100644 --- a/stubs.go +++ b/stubs.go @@ -4,18 +4,32 @@ import ( "encoding/json" "log" "net/http" + "time" ) type StubBuilder struct { - api *APIMock - call *HTTPCall + api *APIMock + call *HTTPCall + delay time.Duration } func (stub *StubBuilder) With(handler http.HandlerFunc) *APIMock { - stub.api.calls[*stub.call] = handler + if stub.delay > 0 { + stub.api.calls[*stub.call] = func(writer http.ResponseWriter, request *http.Request) { + time.Sleep(stub.delay) + handler(writer, request) + } + } else { + stub.api.calls[*stub.call] = handler + } return stub.api } +func (stub *StubBuilder) WithDelay(delay time.Duration) *StubBuilder { + stub.delay = delay + return stub +} + func (stub *StubBuilder) WithStatusCode(statusCode int) *APIMock { return stub.With(func(writer http.ResponseWriter, request *http.Request) { writer.WriteHeader(statusCode) diff --git a/stubs_test.go b/stubs_test.go index 26cbefb..006420e 100644 --- a/stubs_test.go +++ b/stubs_test.go @@ -3,11 +3,16 @@ package mockhttp import ( "net/http" "testing" + "time" "github.com/gavv/httpexpect/v2" - assertions "github.com/stretchr/testify/assert" ) +func (mockedAPI *APIMock) testCall(method, path string, t *testing.T) *httpexpect.Response { + e := httpexpect.Default(t, mockedAPI.GetURL().String()) + return e.Request(method, path).Expect() +} + func TestApiNotStubbedEndpoint(t *testing.T) { t.Parallel() // Arrange @@ -16,14 +21,11 @@ func TestApiNotStubbedEndpoint(t *testing.T) { defer func() { mockedAPI.Close() }() // Act - client := http.Client{} - response, err := client.Get(mockedAPI.GetURL().String() + "/endpoint") + call := mockedAPI.testCall(http.MethodGet, "/endpoint", t) // Assert - assert := assertions.New(t) - assert.NoError(err) testState.assertFailedWithFatal() - assert.Equal(404, response.StatusCode) + call.Status(http.StatusNotFound) } func TestApiStubbedEndpoint(t *testing.T) { @@ -45,11 +47,10 @@ func TestApiStubbedEndpoint(t *testing.T) { }) // Act - e := httpexpect.Default(t, mockedAPI.GetURL().String()) + call := mockedAPI.testCall(http.MethodGet, "/endpoint", t) // Assert - e.GET("/endpoint"). - Expect(). + call. Status(http.StatusCreated). Body().IsEqual("Hello") @@ -70,17 +71,14 @@ func TestApiStubbedEndpointWithJson(t *testing.T) { }{Value: "Hello"}) // Act - e := httpexpect.Default(t, mockedAPI.GetURL().String()) + call := mockedAPI.testCall(http.MethodGet, "/endpoint", t) // Assert testState.assertDidNotFailed() - e.GET("/endpoint"). - Expect(). - Header("Content-Type").IsEqual("application/json") + call.Header("Content-Type").IsEqual("application/json") - responseObject := e.GET("/endpoint"). - Expect(). + responseObject := call. Status(http.StatusOK). JSON().Object() @@ -88,7 +86,7 @@ func TestApiStubbedEndpointWithJson(t *testing.T) { } func TestApiStubbedEndpointWithBody(t *testing.T) { - t.Parallel() + t.Parallel() // Arrange testState := NewTestingMock(t) mockedAPI := API(testState) @@ -100,17 +98,37 @@ func TestApiStubbedEndpointWithBody(t *testing.T) { WithBody(http.StatusOK, body, "text/plain") // Act - e := httpexpect.Default(t, mockedAPI.GetURL().String()) + call := mockedAPI.testCall(http.MethodGet, "/endpoint", t) // Assert testState.assertDidNotFailed() - e.GET("/endpoint"). - Expect(). - Header("Content-Type").IsEqual("text/plain") + call.Header("Content-Type").IsEqual("text/plain") - e.GET("/endpoint"). - Expect(). + call. Status(http.StatusOK). Body().IsEqual("Hello!") } + +func TestApiStubbedEndpointWithDelay(t *testing.T) { + t.Parallel() + // Arrange + testState := NewTestingMock(t) + mockedAPI := API(testState) + defer func() { mockedAPI.Close() }() + body := []byte("Hello!") + + stubbedDelay := 500 * time.Millisecond + + mockedAPI. + Stub(http.MethodPost, "/endpoint"). + WithDelay(stubbedDelay). + WithBody(http.StatusOK, body, "text/plain") + + // Act + call := mockedAPI.testCall(http.MethodPost, "/endpoint", t) + + // Assert + testState.assertDidNotFailed() + call.RoundTripTime().Ge(stubbedDelay) +}