or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assert.mdhttp.mdindex.mdmock.mdrequire.mdsuite.md
tile.json

mock.mddocs/

Mock Package

The mock package provides a comprehensive system for creating mock objects and verifying method calls in tests. It enables you to set expectations on method calls, configure return values, and verify that your code interacts with dependencies correctly.

Package Information

  • Package Name: github.com/stretchr/testify/mock
  • Language: Go
  • Import: import "github.com/stretchr/testify/mock"

Core Imports

import "github.com/stretchr/testify/mock"

Basic Usage

The mock package is built around embedding a Mock object in your test structs. Here's a complete example:

import (
    "testing"
    "github.com/stretchr/testify/mock"
)

// MyInterface defines the interface we want to mock
type MyInterface interface {
    DoSomething(x int, y string) (bool, error)
}

// MyMock embeds mock.Mock to track calls and expectations
type MyMock struct {
    mock.Mock
}

// DoSomething implements MyInterface by delegating to the mock
func (m *MyMock) DoSomething(x int, y string) (bool, error) {
    args := m.Called(x, y)
    return args.Bool(0), args.Error(1)
}

// Test function showing mock setup and verification
func TestMyCode(t *testing.T) {
    // Create mock instance
    mockObj := new(MyMock)

    // Set up expectations
    mockObj.On("DoSomething", 5, "hello").Return(true, nil)

    // Use the mock in your code
    result, err := mockObj.DoSomething(5, "hello")

    // Verify expectations were met
    mockObj.AssertExpectations(t)
}

Capabilities

Core Mock Object

The Mock type is the foundation of the mocking system. It tracks method calls and expectations.

type Mock struct {
    // ExpectedCalls represents the calls that are expected of an object
    ExpectedCalls []*Call

    // Calls holds the calls that were made to this mocked object
    Calls []Call
}

Setting Up Expectations:

func (m *Mock) On(methodName string, arguments ...interface{}) *Call

Starts a description of an expectation for the specified method being called.

Example:

mock.On("MyMethod", arg1, arg2)

Recording Method Calls:

func (m *Mock) Called(arguments ...interface{}) Arguments

Tells the mock object that a method has been called, and gets an array of arguments to return. Panics if the call is unexpected (i.e. not preceded by appropriate .On().Return() calls). If Call.WaitFor is set, blocks until the channel is closed or receives a message.

func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments

Alternative to Called() that explicitly specifies the method name. Tells the mock object that the given method has been called, and gets an array of arguments to return.

Verification Methods:

func (m *Mock) AssertExpectations(t TestingT) bool

Asserts that everything specified with On and Return was in fact called as expected. Calls may have occurred in any order.

func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool

Asserts that the method was called with the specified arguments. It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.

func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool

Asserts that the method was not called with the specified arguments. It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.

func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool

Asserts that the method was called exactly the specified number of times.

Utility Methods:

func (m *Mock) TestData() objx.Map

Returns a map that holds any data that might be useful for testing. Testify ignores this data completely, allowing you to store whatever you like.

func (m *Mock) Test(t TestingT)

Sets the TestingT on which errors will be reported, otherwise errors will cause a panic. Test should not be called on an object that is going to be used in a goroutine other than the one running the test function.

func (m *Mock) IsMethodCallable(t TestingT, methodName string, arguments ...interface{}) bool

Checks whether the method can be called. If the method was called more than its configured Repeatability, returns false.

func (m *Mock) String() string

Provides a %v format string for Mock. Note: this is used implicitly by Arguments.Diff if a Mock is passed. It exists because Go's default %v formatting traverses the struct without acquiring the mutex, which is detected by go test -race.

Call Configuration

The Call type represents a method call expectation and provides methods for configuring return values, call counts, timing, and more.

type Call struct {
    Parent *Mock

    // Method is the name of the method that was or will be called
    Method string

    // Arguments holds the arguments of the method
    Arguments Arguments

    // ReturnArguments holds the arguments that should be returned when
    // this method is called
    ReturnArguments Arguments

    // Repeatability is the number of times to return the return arguments
    // when setting expectations. 0 means to always return the value.
    Repeatability int

    // WaitFor holds a channel that will be used to block the Return until
    // it either receives a message or is closed. nil means it returns immediately.
    WaitFor <-chan time.Time

    // RunFn holds a handler used to manipulate arguments content that are
    // passed by reference. It's useful when mocking methods such as
    // unmarshalers or decoders.
    RunFn func(Arguments)

    // PanicMsg holds msg to be used to mock panic on the function call.
    // If the PanicMsg is set to a non-nil string, the function call will panic
    // irrespective of other settings.
    PanicMsg *string
}

Return Value Configuration:

func (c *Call) Return(returnArguments ...interface{}) *Call

Specifies the return arguments for the expectation.

Example:

Mock.On("DoSomething").Return(errors.New("failed"))
func (c *Call) Run(fn func(args Arguments)) *Call

Sets a handler to be called before returning. It can be used when mocking a method (such as an unmarshaler) that takes a pointer to a struct and sets properties in such struct.

Example:

Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}")).Return().Run(func(args Arguments) {
    arg := args.Get(0).(*map[string]interface{})
    arg["foo"] = "bar"
})

Call Count Expectations:

func (c *Call) Once() *Call

Indicates that the mock should only return the value once.

Example:

Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
func (c *Call) Twice() *Call

Indicates that the mock should only return the value twice.

Example:

Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
func (c *Call) Times(i int) *Call

Indicates that the mock should only return the value the specified number of times.

Example:

Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
func (c *Call) Maybe() *Call

Allows the method call to be optional. Not calling an optional method will not cause an error while asserting expectations.

Timing and Ordering:

func (c *Call) After(d time.Duration) *Call

Sets how long to block until the call returns.

Example:

Mock.On("MyMethod", arg1, arg2).After(time.Second)
func (c *Call) WaitUntil(w <-chan time.Time) *Call

Sets the channel that will block the mock's return until it's closed or a message is received.

Example:

Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
func (c *Call) NotBefore(calls ...*Call) *Call

Indicates that the mock should only be called after the referenced calls have been called as expected. The referenced calls may be from the same mock instance and/or other mock instances.

Example:

Mock.On("Do").Return(nil).NotBefore(
    Mock.On("Init").Return(nil)
)

Panic Configuration:

func (c *Call) Panic(msg string) *Call

Specifies that the function call should panic with the given message.

Example:

Mock.On("DoSomething").Panic("test panic")

Call Management:

func (c *Call) On(methodName string, arguments ...interface{}) *Call

Chains a new expectation description onto the mocked interface. This allows fluent syntax.

Example:

Mock.
    On("MyMethod", 1).Return(nil).
    On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
func (c *Call) Unset() *Call

Removes all mock handlers that satisfy the call instance arguments from being called. Only supported on call instances with static input arguments.

Example:

Mock.
    On("MyMethod", 2, 2).Return(0).
    On("MyMethod", 3, 3).Return(0).
    On("MyMethod", Anything, Anything).Return(0)
Mock.On("MyMethod", 3, 3).Unset()
// Only "MyMethod(2, 2)" handler remains

Arguments Type

Arguments represents method arguments or return values and provides type-safe accessors.

type Arguments []interface{}

Accessing Arguments:

func (args Arguments) Get(index int) interface{}

Returns the argument at the specified index.

func (args Arguments) String(indexOrNil ...int) string

Gets the argument at the specified index as a string. Panics if there is no argument, or if the argument is of the wrong type.

If no index is provided, String() returns a complete string representation of the arguments.

func (args Arguments) Int(index int) int

Gets the argument at the specified index as an int. Panics if there is no argument, or if the argument is of the wrong type.

func (args Arguments) Bool(index int) bool

Gets the argument at the specified index as a bool. Panics if there is no argument, or if the argument is of the wrong type.

func (args Arguments) Error(index int) error

Gets the argument at the specified index as an error. Panics if there is no argument, or if the argument is of the wrong type.

Comparison and Verification:

func (args Arguments) Is(objects ...interface{}) bool

Gets whether the objects match the arguments specified.

func (args Arguments) Diff(objects []interface{}) (string, int)

Gets a string describing the differences between the arguments and the specified objects. Returns the diff string and number of differences found.

func (args Arguments) Assert(t TestingT, objects ...interface{}) bool

Compares the arguments with the specified objects and fails the test if they do not exactly match.

Argument Matchers

Argument matchers provide flexible matching for expected method arguments.

Anything Matcher:

const Anything = "mock.Anything"

Used in Diff and Assert when the argument being tested shouldn't be taken into consideration. Matches any argument value.

Example:

Mock.On("MyMethod", Anything, 42).Return(nil)

Type-Based Matchers:

type AnythingOfTypeArgument = anythingOfTypeArgument

func AnythingOfType(t string) AnythingOfTypeArgument

Returns a special value containing the name of the type to check for. The type name will be matched against the type name returned by reflect.Type.String().

Example:

args.Assert(t, AnythingOfType("string"), AnythingOfType("int"))
Mock.On("Do", mock.AnythingOfType("string"))
type IsTypeArgument struct {
    // contains unexported fields
}

func IsType(t interface{}) *IsTypeArgument

Returns an IsTypeArgument object containing the type to check for. You can provide a zero-value of the type to check. This is an alternative to AnythingOfType.

Example:

args.Assert(t, IsType(""), IsType(0))

Custom Matcher:

func MatchedBy(fn interface{}) argumentMatcher

Can be used to match a mock call based on only certain properties from a complex struct or some calculation. It takes a function that will be evaluated with the called argument and will return true when there's a match and false otherwise.

The function fn must accept a single argument (of the expected type) and return a bool. If fn doesn't match the required signature, MatchedBy() panics.

Example:

m.On("Do", MatchedBy(func(req *http.Request) bool {
    return req.Host == "example.com"
}))

Functional Options Matcher:

type FunctionalOptionsArgument struct {
    // contains unexported fields
}

func FunctionalOptions(values ...interface{}) *FunctionalOptionsArgument

Returns a FunctionalOptionsArgument object containing the expected functional-options to check for.

Example:

args.Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613)))
func (f *FunctionalOptionsArgument) String() string

Returns the string representation of FunctionalOptionsArgument.

Helper Functions

func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool

Asserts that everything specified with On and Return of the specified objects was in fact called as expected. Calls may have occurred in any order.

func InOrder(calls ...*Call)

Defines the order in which the calls should be made.

Example:

InOrder(
    Mock.On("init").Return(nil),
    Mock.On("Do").Return(nil),
)

TestingT Interface

type TestingT interface {
    Logf(format string, args ...interface{})
    Errorf(format string, args ...interface{})
    FailNow()
}

TestingT is an interface wrapper around *testing.T and *testing.B.

Complete Usage Examples

Basic Mock with Verification

import (
    "testing"
    "github.com/stretchr/testify/mock"
)

// Define interface to mock
type Database interface {
    Save(key string, value interface{}) error
    Load(key string) (interface{}, error)
}

// Create mock implementation
type MockDatabase struct {
    mock.Mock
}

func (m *MockDatabase) Save(key string, value interface{}) error {
    args := m.Called(key, value)
    return args.Error(0)
}

func (m *MockDatabase) Load(key string) (interface{}, error) {
    args := m.Called(key)
    return args.Get(0), args.Error(1)
}

// Test using the mock
func TestDatabaseOperations(t *testing.T) {
    mockDB := new(MockDatabase)

    // Set up expectations
    mockDB.On("Save", "user:123", mock.Anything).Return(nil)
    mockDB.On("Load", "user:123").Return("John Doe", nil)

    // Execute code under test
    err := mockDB.Save("user:123", "John Doe")
    if err != nil {
        t.Fatal(err)
    }

    result, err := mockDB.Load("user:123")
    if err != nil {
        t.Fatal(err)
    }

    // Verify expectations
    mockDB.AssertExpectations(t)
    mockDB.AssertCalled(t, "Save", "user:123", mock.Anything)

    if result != "John Doe" {
        t.Errorf("Expected 'John Doe', got %v", result)
    }
}

Mock with Call Count Expectations

func TestCallCounts(t *testing.T) {
    mockDB := new(MockDatabase)

    // Expect Save to be called exactly twice
    mockDB.On("Save", "config", mock.Anything).Return(nil).Twice()

    // Expect Load to be called at least once (optional expectations)
    mockDB.On("Load", "settings").Return("default", nil).Maybe()

    // Execute operations
    mockDB.Save("config", "value1")
    mockDB.Save("config", "value2")

    // Verify expectations (will pass because Load was optional)
    mockDB.AssertExpectations(t)
    mockDB.AssertNumberOfCalls(t, "Save", 2)
}

Mock with Custom Argument Matchers

import "net/http"

type HTTPClient interface {
    Do(req *http.Request) (*http.Response, error)
}

type MockHTTPClient struct {
    mock.Mock
}

func (m *MockHTTPClient) Do(req *http.Request) (*http.Response, error) {
    args := m.Called(req)
    return args.Get(0).(*http.Response), args.Error(1)
}

func TestCustomMatcher(t *testing.T) {
    mockClient := new(MockHTTPClient)

    // Match requests to specific host
    mockClient.On("Do", mock.MatchedBy(func(req *http.Request) bool {
        return req.Host == "api.example.com"
    })).Return(&http.Response{StatusCode: 200}, nil)

    // Create request
    req, _ := http.NewRequest("GET", "https://api.example.com/data", nil)

    // Execute
    resp, err := mockClient.Do(req)

    // Verify
    if err != nil {
        t.Fatal(err)
    }
    if resp.StatusCode != 200 {
        t.Errorf("Expected status 200, got %d", resp.StatusCode)
    }
    mockClient.AssertExpectations(t)
}

Mock with Run Function for Side Effects

type JSONDecoder interface {
    Decode(v interface{}) error
}

type MockDecoder struct {
    mock.Mock
}

func (m *MockDecoder) Decode(v interface{}) error {
    args := m.Called(v)
    return args.Error(0)
}

func TestDecoderWithSideEffects(t *testing.T) {
    mockDecoder := new(MockDecoder)

    // Use Run to populate the passed-in struct
    mockDecoder.On("Decode", mock.AnythingOfType("*map[string]interface{}")).
        Return(nil).
        Run(func(args mock.Arguments) {
            // Modify the argument that was passed in
            m := args.Get(0).(*map[string]interface{})
            (*m)["name"] = "John"
            (*m)["age"] = 30
        })

    // Execute
    result := make(map[string]interface{})
    err := mockDecoder.Decode(&result)

    // Verify
    if err != nil {
        t.Fatal(err)
    }
    if result["name"] != "John" || result["age"] != 30 {
        t.Errorf("Unexpected result: %v", result)
    }
    mockDecoder.AssertExpectations(t)
}

Mock with Timing Control

func TestTimingControl(t *testing.T) {
    mockDB := new(MockDatabase)

    // Simulate slow operation
    mockDB.On("Load", "slow-key").
        Return("data", nil).
        After(100 * time.Millisecond)

    // Measure execution time
    start := time.Now()
    mockDB.Load("slow-key")
    duration := time.Since(start)

    if duration < 100*time.Millisecond {
        t.Error("Expected operation to take at least 100ms")
    }

    mockDB.AssertExpectations(t)
}

Mock with Call Ordering

func TestCallOrdering(t *testing.T) {
    mockDB := new(MockDatabase)

    // Define expected call order
    initCall := mockDB.On("Save", "init", "true").Return(nil)
    processCall := mockDB.On("Save", "status", "processing").Return(nil).NotBefore(initCall)
    mockDB.On("Save", "status", "complete").Return(nil).NotBefore(processCall)

    // Execute in correct order
    mockDB.Save("init", "true")
    mockDB.Save("status", "processing")
    mockDB.Save("status", "complete")

    // Verify expectations
    mockDB.AssertExpectations(t)
}

// Alternative using InOrder
func TestInOrder(t *testing.T) {
    mockDB := new(MockDatabase)

    mock.InOrder(
        mockDB.On("Save", "init", "true").Return(nil),
        mockDB.On("Save", "status", "processing").Return(nil),
        mockDB.On("Save", "status", "complete").Return(nil),
    )

    // Execute in correct order
    mockDB.Save("init", "true")
    mockDB.Save("status", "processing")
    mockDB.Save("status", "complete")

    mockDB.AssertExpectations(t)
}

Mock with Panic Expectation

func TestPanicExpectation(t *testing.T) {
    mockDB := new(MockDatabase)

    // Configure mock to panic
    mockDB.On("Save", "invalid", mock.Anything).Panic("database connection lost")

    // Test panic behavior
    defer func() {
        if r := recover(); r == nil {
            t.Error("Expected panic but didn't get one")
        }
    }()

    mockDB.Save("invalid", "data")
}

Multiple Mocks Verification

func TestMultipleMocks(t *testing.T) {
    mockDB := new(MockDatabase)
    mockCache := new(MockDatabase) // Using same type for example

    // Set up expectations on both mocks
    mockDB.On("Save", "user:123", "John").Return(nil)
    mockCache.On("Save", "user:123", "John").Return(nil)

    // Execute operations
    mockDB.Save("user:123", "John")
    mockCache.Save("user:123", "John")

    // Verify all mocks at once
    mock.AssertExpectationsForObjects(t, mockDB, mockCache)
}

Advanced Argument Matching

func TestAdvancedMatching(t *testing.T) {
    mockDB := new(MockDatabase)

    // Match any string for key, specific type for value
    mockDB.On("Save",
        mock.AnythingOfType("string"),
        mock.IsType(&User{}),
    ).Return(nil)

    // Match with Anything constant
    mockDB.On("Load", mock.Anything).Return(nil, nil)

    // Execute with various arguments
    mockDB.Save("user:1", &User{Name: "John"})
    mockDB.Save("user:2", &User{Name: "Jane"})
    mockDB.Load("any-key")

    mockDB.AssertExpectations(t)
}

type User struct {
    Name string
}