httpmock

package module
v1.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2021 License: MIT Imports: 8 Imported by: 0

README

This is a fork of dankinder's httpmock

This is a fork of dankinder/httpmock in order to add some more useful functions. The aim of these functions is to make the library more "batteries included". This means that you'll find functions that will probably help you do what you want 98% of the time.

Added functions

  1. MockHandler.OnHandle(): Typed version of handler.On("Handle", ...)
  2. MockHandler.OnHandleWithHeaders(): : Typed version of handler.On("HandleWithHeaders", ...)
  3. MockHandler.OnRequestWithAnyBody(): typed pass-through to handler.On(Handle, method, path, mock.Anthing (body))
  4. MockHandler.OnAnyRequestToPath(): typed pass-through to handler.On(Handle, mock.Anything (method), path, mock.Anything (body))
  5. MockHandler.OnAnyRequest(): typed pass-through to handler.On(Handle, mock.Anything (method), mock.Anything(path), mock.Anything (body))
Quick Examples of added functionality
mHandler := &httpmock.MockHandler{}
somePath := "/some/path/in-your-api"

// Will match any request to somePath (GET/POST/PUT etc) and with any request body 
mHandler.OnAnyRequestToPath(somePath).Return(httpmock.Response{
	Body: []byte(`{"status": "ok"}`),
})

s := httpmock.NewServer(mHandler)
defer s.Close()

// Make requests to s.URL() in your code

// Can also make this a defer right after declaration
mHandler.AssertExpectations(t)

Httpmock

GoDoc Go Report Card Build Status

This library builds on Go's built-in httptest library, adding a more mockable interface that can be used easily with other mocking tools like testify/mock. It does this by providing a Handler that receives HTTP components as separate arguments rather than a single *http.Request object.

Where the typical http.Handler interface is:

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

This library provides a server with the following interface, which works naturally with mocking libraries:

// Handler is the interface used by httpmock instead of http.Handler so that it can be mocked very easily.
type Handler interface {
	Handle(method, path string, body []byte) Response
}

Examples

The most primitive example, the OKHandler, just returns 200 OK to everything.

s := httpmock.NewServer(&httpmock.OKHandler{})
defer s.Close()

// Make any requests you want to s.URL(), using it as the mock downstream server

This example uses MockHandler, a Handler that is a testify/mock object.

downstream := &httpmock.MockHandler{}

// A simple GET that returns some pre-canned content
downstream.On("Handle", "GET", "/object/12345", mock.Anything).Return(httpmock.Response{
    Body: []byte(`{"status": "ok"}`),
})

s := httpmock.NewServer(downstream)
defer s.Close()

//
// Make any requests you want to s.URL(), using it as the mock downstream server
//

downstream.AssertExpectations(t)

If instead you wish to match against headers as well, a slightly different httpmock object can be used (please note the change in function name to be matched against):

downstream := &httpmock.MockHandlerWithHeaders{}

// A simple GET that returns some pre-canned content and a specific header
downstream.On("HandleWithHeaders", "GET", "/object/12345", MatchHeader("MOCK", "this"), mock.Anything).Return(httpmock.Response{
    Body: []byte(`{"status": "ok"}`),
})

// ... same as above

The httpmock package also provides helpers for checking calls using json objects, like so:

// This tests a hypothetical "echo" endpoint, which returns the body we pass to it.
type Obj struct {
    A string `json:"a"`
}

o := &Obj{A: "aye"}

// JSONMatcher ensures that this mock is triggered only when the HTTP body, when deserialized, matches the given
// object. Here, this mock response will get triggered only if `{"a":"aye"}` is sent.
downstream.On("Handle", "POST", "/echo", httpmock.JSONMatcher(o)).Return(httpmock.Response{
    Body: httpmock.ToJSON(o),
})

Documentation

Overview

Package httpmock builds on httptest, providing easier API mocking.

Essentially all httpmock does is implement a similar interface to httptest, but using a Handler that receives the HTTP method, path, and body rather than a request object. This makes it very easy to use a featureful mock as the handler, e.g. github.com/stretchr/testify/mock

Examples

s := httpmock.NewServer(&httpmock.OKHandler{})
defer s.Close()

// Make any requests you want to s.URL(), using it as the mock downstream server

This example uses MockHandler, a Handler that is a github.com/stretchr/testify/mock object.

downstream := &httpmock.MockHandler{}

// A simple GET that returns some pre-canned content
downstream.On("Handle", "GET", "/object/12345", mock.Anything).Return(httpmock.Response{
	Body: []byte(`{"status": "ok"}`),
})

s := httpmock.NewServer(downstream)
defer s.Close()

//
// Make any requests you want to s.URL(), using it as the mock downstream server
//

downstream.AssertExpectations(t)

If instead you wish to match against headers as well, a slightly different httpmock object can be used (please note the change in function name to be matched against):

downstream := &httpmock.MockHandlerWithHeaders{}

// A simple GET that returns some pre-canned content
downstream.On("HandleWithHeaders", "GET", "/object/12345", MatchHeader("MOCK", "this"), mock.Anything).Return(httpmock.Response{
    Body: []byte(`{"status": "ok"}`),
})

// ... same as above

Httpmock also provides helpers for checking calls using json objects, like so:

// This tests a hypothetical "echo" endpoint, which returns the body we pass to it.
type Obj struct {
	A string `json:"a"`
	B string `json:"b"`
}

o := &Obj{A: "ay", B: "bee"}

// JSONMatcher ensures that this mock is triggered only when the HTTP body, when deserialized, matches the given
// object.
downstream.On("Handle", "POST", "/echo", httpmock.JSONMatcher(o)).Return(httpmock.Response{
	Body: httpmock.ToJSON(o),
})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HeaderMatcher added in v1.1.0

func HeaderMatcher(key, value string) interface{}

HeaderMatcher matches the presence of a header named key that has a given value. Other headers are allowed to exist and are not checked.

func JSONMatcher

func JSONMatcher(o1 interface{}) interface{}

JSONMatcher returns a mock.MatchedBy func to check if the argument is the json form of the provided object. See the github.com/stretchr/testify/mock documentation and example in httpmock.go.

func MultiHeaderMatcher added in v1.1.0

func MultiHeaderMatcher(desiredHeaders http.Header) interface{}

MultiHeaderMatcher matches the presence and content of multiple headers. Other headers besides those within desiredHeaders are allowed to exist and are not checked.

func ToJSON

func ToJSON(obj interface{}) []byte

ToJSON is a convenience function for converting an object to JSON inline. It panics on failure, so should be used only in test code.

Types

type Handler

type Handler interface {
	Handle(method, path string, body []byte) Response
}

Handler is the interface used by httpmock instead of http.Handler so that it can be mocked very easily.

type HandlerWithHeaders added in v1.1.0

type HandlerWithHeaders interface {
	Handler
	HandleWithHeaders(method, path string, headers http.Header, body []byte) Response
}

HandlerWithHeaders is the interface used by httpmock instead of http.Handler so that it can be mocked very easily, it additionally allows matching on headers.

type MockHandler

type MockHandler struct {
	mock.Mock
}

MockHandler is a httpmock.Handler that uses github.com/stretchr/testify/mock.

func (*MockHandler) Handle

func (m *MockHandler) Handle(method, path string, body []byte) Response

Handle makes this implement the Handler interface.

func (*MockHandler) HandleWithHeaders added in v1.1.0

func (m *MockHandler) HandleWithHeaders(method, path string, headers http.Header, body []byte) Response

HandleWithHeaders makes this implement the HandlerWithHeaders interface.

func (*MockHandler) OnAnyHeadersToPath added in v1.2.3

func (m *MockHandler) OnAnyHeadersToPath(path string) *mock.Call

func (*MockHandler) OnAnyHeadersWithAnyBody added in v1.2.3

func (m *MockHandler) OnAnyHeadersWithAnyBody(method, path string) *mock.Call

func (*MockHandler) OnAnyRequest added in v1.2.0

func (m *MockHandler) OnAnyRequest() *mock.Call

OnAnyRequestToPath is a typed, pass-through version of the mock.Mock.On() method to Handle(). Any request will be caught by this.

func (*MockHandler) OnAnyRequestToPath added in v1.2.0

func (m *MockHandler) OnAnyRequestToPath(path string) *mock.Call

OnAnyRequestToPath is a typed, pass-through version of the mock.Mock.On() method to Handle(). Any method and any request body. Only the path is specified

func (*MockHandler) OnHandle added in v1.1.0

func (m *MockHandler) OnHandle(method, path string, body []byte) *mock.Call

OnHandle is a typed, pass-through version of the mock.Mock.On() method to Handle()

func (*MockHandler) OnHandleWithHeaders added in v1.1.0

func (m *MockHandler) OnHandleWithHeaders(method, path string, headers http.Header, body []byte) *mock.Call

OnHandleWithHeaders is a typed, pass-through version of the mock.Mock.On() method to HandleWithHeaders()

func (*MockHandler) OnRequestWithAnyBody added in v1.2.0

func (m *MockHandler) OnRequestWithAnyBody(method, path string) *mock.Call

OnHandleAnyBody is a typed, pass-through version of the mock.Mock.On() method to Handle() with a body of mock.Anything

type OKHandler

type OKHandler struct {
}

OKHandler is a simple Handler that returns 200 OK responses for any request.

func (*OKHandler) Handle

func (r *OKHandler) Handle(method, path string, body []byte) Response

Handle makes this implement the Handler interface.

type Response

type Response struct {
	// The HTTP status code to write (default: 200)
	Status int
	// Headers to add to the response
	Header http.Header
	// The response body to write (default: no body)
	Body []byte
}

Response holds the response a handler wants to return to the client.

func OkJsonResponse added in v1.2.2

func OkJsonResponse(responseData interface{}) Response

OkJsonResponse will return an httpmock.Response with given response data object rendered into JSON and a 200 status code.

NOTE: This function will panic if marshalling the JSON fails, so only use in test code

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server listens for requests and interprets them into calls to your Handler.

func NewServer

func NewServer(handler Handler) *Server

NewServer constructs a new server and starts it (compare to httptest.NewServer). It needs to be Closed()ed. If you pass a handler that conforms to the HandlerWithHeaders interface, when requests are received, the HandleWithHeaders method will be called rather than Handle.

func NewUnstartedServer

func NewUnstartedServer(handler Handler) *Server

NewUnstartedServer constructs a new server but doesn't start it (compare to httptest.NewUnstartedServer). If you pass a handler that conforms to the HandlerWithHeaders interface, when requests are received, the HandleWithHeaders method will be called rather than Handle.

func (*Server) Close

func (s *Server) Close()

Close shuts down a started server.

func (*Server) Start

func (s *Server) Start()

Start starts an unstarted server.

func (*Server) URL

func (s *Server) URL() string

URL is the URL for the local test server, i.e. the value of httptest.Server.URL

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL