BudiBadu Logo

Samplebadu

Code with Example
BudiBadu Logo
Samplebadu

Go by Example: Mocking with Testify

Go 1.23

Learn to mock dependencies in tests using the `testify` toolkit. This example demonstrates creating mock objects, setting expectations for method calls, and asserting behavior, allowing for isolated and deterministic unit tests.

Code

package main

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

// ServiceInterface defines the interface we want to mock
type ServiceInterface interface {
    DoSomething(int) (bool, error)
}

// MyMockService is a mock implementation of ServiceInterface
type MyMockService struct {
    mock.Mock
}

func (m *MyMockService) DoSomething(number int) (bool, error) {
    args := m.Called(number)
    return args.Bool(0), args.Error(1)
}

func TestSomething(t *testing.T) {
    // Create an instance of our mock object
    testObj := new(MyMockService)

    // Setup expectations
    testObj.On("DoSomething", 123).Return(true, nil)

    // Call the code we are testing
    result, err := testObj.DoSomething(123)

    // Assert expectations
    assert.NoError(t, err)
    assert.True(t, result)
    testObj.AssertExpectations(t)
}

Explanation

Mocking allows you to test code in isolation by replacing real dependencies (like databases or APIs) with simulated objects. The testify/mock package is the industry standard for this in Go.

How to use Testify Mocks:

  • Embed: Embed mock.Mock in your struct.
  • Implement: Implement the interface methods, calling args := m.Called(...) to record the call.
  • Expect: In tests, use obj.On("Method", args).Return(values) to define behavior.
  • Assert: Call obj.AssertExpectations(t) at the end to ensure all expected calls actually happened.

Code Breakdown

15
We embed mock.Mock into our struct. This gives MyMockService all the necessary methods (On, Called, AssertExpectations) to function as a mock.
19
m.Called(number) is the core of the mock. It records that DoSomething was called with 'number' and returns an Arguments object containing the return values we set up in the test.
20
We extract the return values from the Arguments object using type-safe methods like Bool(0) and Error(1). These correspond to the first and second return values.
28
testObj.On("DoSomething", 123).Return(true, nil) sets up an expectation: "When DoSomething is called with argument 123, return true and nil".
36
testObj.AssertExpectations(t) asserts that everything we expected to happen actually happened. If DoSomething wasn't called, or was called with different arguments, the test would fail here.