gock

package
v0.0.23 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2024 License: MIT Imports: 6 Imported by: 0

README

Package testing/gock

Goal of this package is to provide a small controller to isolate testing of services (gateways) by mocking the network communication using gock.

Note: Since the controller is focused on testing, it does not support the same networking and observation features of gock and requires manual transport interception setup. However, the interface is mainly compatible.

Example usage

Just create a new controller on each test, connect it to your HTTP clients or client wrappers, and then use it to create HTTP mock request/response cycles as usual.

func TestUnit(t *testing.T) {
    // Given
    gock := gock.NewController(t)

    client := &http.Client{}
    gock.InterceptClient(client)

    gock.New("http://foo.com").Get("/bar").Times(1).
        Reply(200).BodyString("result")

    // When
    ...
}

The controller is fully integrated in to the mock-framework, so that you can just request the controller via the gomock constructor mock.Get(mocks, gock.NewGock) (see Example)

Migration from Gock

Migration from gock to this package is straight forward. You just add the controller creation at the begin of your test giving it the name gock and hand it over to all methods creating HTTP request/response mocks. The mock creation than happens as usual.

func TestUnit(t *testing.T) {
    // Given
    gock := gock.NewController(t)

    ...

    gock.New("http://foo.com").Get("/bar").Times(1).
        Reply(200).BodyString("result")

    // WHen
    ...
}

Since the controller does not intercept all transports by default, you need to setup transport interception manually. This can happen in three different ways. If you have access to the HTTP request/response client, you can use the usual InterceptClient (and RestoreClient) methods.

func TestUnit(t *testing.T) {
    // Given
    gock := tock.Controller(t)

    ...

    client := &http.Client{}
    gock.InterceptClient(client)
    defer gock.RestoreClient(client) // optional

    // When
    ...
}

Customized HTTP clients e.g. resty may not give direct access to the transport but offer the ability to set a http.RoundTripper. The controller implements this interface and therefore can be simply used as drop in entity.

func TestUnit(t *testing.T) {
    // Given
    gock := tock.Controller(t)

    ...

    client := resty.New()
    client.setTransport(gock)

    // When
    ...
}

As a last resort, you can also intercept the http.DefaultTransport, however, this is not advised, since it will destroy the test isolation that is goal of this controller framework. In this case you should use gock directly.

Integration with mock-framework

The Gock-controller framework supports a simple integration with the mock framework for gomock: it simply provides constructor that accepts the gomock-controller. Using constructor, it is possible to create the usual setup methods similar as described in the generic mock service call pattern.

func GockCall(
    url, path string, input..., status int, output..., error,
) mock.SetupFunc {
    return func(mocks *Mocks) any {
        mock.Get(mocks, gock.NewGock).New(url).Get(path).Times(1).
            Reply(status)...
        return nil
    }
}

Note: While this already nicely integrates the mock controller creation, call setup, and validation, it currently provides no support for call order validation as gomock supports it.

Documentation

Overview

Package gock provides a small controller to isolate testing of services (gateways) by mocking the network communication using.

Index

Constants

This section is empty.

Variables

View Source
var ErrCannotMatch = gock.ErrCannotMatch

ErrCannotMatch is the re-exported error for a failed match.

Functions

This section is empty.

Types

type Controller

type Controller struct {

	// MockStore the attached HTTP request/response mock storage.
	MockStore *MockStore
	// contains filtered or unexported fields
}

Controller is a Gock based HTTP request/response mock controller.

func NewController

func NewController(t test.Test) *Controller

NewController creates a new HTTP request/response mock controller.

func NewGock

func NewGock(ctrl *gomock.Controller) *Controller

NewGock creates a new HTTP request/response mock controller from the given go mock controller.

func (*Controller) Cleanup

func (ctrl *Controller) Cleanup()

Cleanup checks if all the HTTP request/response mocks that were expected to be called have been called. This function is automatically registered with the test controller and will be called when the test is finished.

func (*Controller) InterceptClient

func (ctrl *Controller) InterceptClient(client *http.Client)

InterceptClient allows to intercept HTTP traffic of a custom http.Client that uses a non default http.Transport/http.RoundTripper implementation.

func (*Controller) New

func (ctrl *Controller) New(uri string) *gock.Request

New creates and registers a new HTTP request/response mock with given full qualified URI and default settings. It returns the request builder for setup of HTTP request and response mock details.

func (*Controller) RestoreClient

func (*Controller) RestoreClient(client *http.Client)

RestoreClient allows to disable and restore the original transport in the given http.Client.

func (*Controller) RoundTrip

func (ctrl *Controller) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip receives HTTP requests and matches them against the registered HTTP request/response mocks. If a match is found it is used to construct the response, else the request is tracked as unmatched. If networing is enabled, the original transport is used to handle the request to .

This method implements the `http.RoundTripper` interface and is used by attaching the controller to a `http.client` via `SetTransport`.

type MockStore

type MockStore struct {

	// Matcher template used when creating new HTTP request/response mocks.
	Matcher *gock.MockMatcher
	// contains filtered or unexported fields
}

MockStore store for HTTP request/response mocks.

func NewStore

func NewStore(matcher *gock.MockMatcher) *MockStore

NewStore creates a new mock registry for HTTP request/response mocks. If nil is provided as matcher the default matcher is used.

func (*MockStore) All

func (s *MockStore) All() []gock.Mock

All returns the current list of registered HTTP request/response mocks.

func (*MockStore) Clean

func (s *MockStore) Clean() *MockStore

Clean cleans the store removing disabled or obsolete HTTP request/response mocks.

func (*MockStore) Exists

func (s *MockStore) Exists(m gock.Mock) bool

Exists checks if the given HTTP request/response mocks is already registered.

func (*MockStore) Flush

func (s *MockStore) Flush() *MockStore

Flush flushes the current stack of registered HTTP request/response mocks.

func (*MockStore) IsDone

func (s *MockStore) IsDone() bool

IsDone returns true if all the registered HTTP request/response mocks have been triggered successfully.

func (*MockStore) IsPending

func (s *MockStore) IsPending() bool

IsPending returns true if there are pending HTTP request/response mocks.

func (*MockStore) Match

func (s *MockStore) Match(req *http.Request) (gock.Mock, error)

Match matches the given `http.Request` with the registered HTTP request mocks. It is returning the mock that matches or an error, if a matching function fails. If no HTTP mock request matches nothing is returned.

func (*MockStore) NewMock

func (s *MockStore) NewMock(uri string) gock.Mock

NewMock creates and registers a new HTTP request/response mock with default settings and returns the mock.

func (*MockStore) Pending

func (s *MockStore) Pending() []gock.Mock

Pending returns a slice of the pending HTTP request/response mocks. As a side effect the mock store is cleaned up similar as calling `Clean` on it.

func (*MockStore) Register

func (s *MockStore) Register(mock gock.Mock) *MockStore

Register registers a new HTTP request/response mocks in the current stack.

func (*MockStore) Remove

func (s *MockStore) Remove(m gock.Mock) *MockStore

Remove removes a registered HTTP request/response mocks by reference.

type Transport

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

Transport is a small transport implementation delegating requests to the owning HTTP request/response mock controller.

func NewTransport

func NewTransport(
	controller *Controller, transport http.RoundTripper,
) *Transport

NewTransport creates a new *Transport with no responders.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip delegates to the controller `RoundTrip` method.

Jump to

Keyboard shortcuts

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