Skip to content

Latest commit

History

History

mock

Folders and files

NameName
Last commit message
Last commit date

parent directory

..

mock: Downstream Mocking

Build Status Go Reference

Overview

Package mock makes it possible to implement downstream service dependency mocks that run in-memory.

Conceptually a test may want to verify that a service method is called multiple times with different values each time. The mock package Add method can be used by the test to record each method call and verify that the correct values are used.

Alternatively (or complementarily) the Set method defines a mock that is used for all method calls by the test. If both Add and Set are used by the test then the mocks recorded by Add are used first.

Additionally, there is a cmg (Clue Mock Generator) command line tool that generates dependency mocks from all exported interfaces in a given package so they do not need to be written by hand.

Usage

Creating a Dependency Mock

// mock implementation of the `prices` service
type mock struct {
        *mock.Mock    // Embed the mock package Mock struct which provides the mock API
        t *testing.T
}

func newMock(t *testing.T) *mock {
        return &mock{mock.New(), t}
}

// mock implementation of the GetPrices method. The implementation leverages
// the mock package to replay a sequence of calls.
func (m *mock) GetPrices(ctx context.Context, first, last time.Time, nodeID string) ([]*Price, error) {
        if f := m.Next("GetPrices"); f != nil { // Get the next mock in the sequence (or the permanent mock)
                return f.(func(ctx, time.Time, time.Time, string) ([]*Price, error))(ctx, first, last, nodeID)
        }
        m.t.Error("unexpected GetPrices call")
}

Using a Mock in a Test

Sequences are created using the Add method while permanent mocks are created using Set. The method HasMore returns true if a sequence has been set and has not been entirely consumed.

// Create a new mock client (defined above).
mock := newMock(t)

// Add a mock call for the GetPrices method.
mock.Add("GetPrices", getPricesFunc)

// Call the mock.
prices, err := mock.GetPrices(ctx, firstHour, lastHour, nodeID)

// Validate prices and err
if err != nil {
        t.Errorf("GetPrices returned %v", err)
}

// Make sure entire sequence has been consumed (in this example there is only
// one call).
if mock.HasMore() {
        t.Error("GetPrices was not called")
}

Clue Mock Generator

Installation

go install goa.design/clue/mock/cmd/cmg

Usage

The Clue Mock Generator can be invoked using the same package path syntax as other Go tools and it can accept multiple packages:

cmg gen ./example/weather/services/...