A powerful Go code generation tool that automatically creates type-safe mock implementations from interface definitions. Designed to work seamlessly with testify/mock, go-mock eliminates boilerplate and provides a fluent, type-safe API for setting up test expectations and assertions.
Writing mocks manually is tedious and error-prone. go-mock analyzes your Go interfaces and generates comprehensive mock implementations with:
- Type-safe method setup - No more casting or type assertions
- Fluent API - Chain method calls for readable test setup
- Smart parameter handling - Automatic context removal, variadic parameters, generics support
- Comprehensive assertions - Verify calls, arguments, and invocation counts
- Complex type support - Handles channels, anonymous interfaces, function types, and more
- ✅ Automatic code generation via
//go:generatedirectives - ✅ Type-safe mock implementations with compile-time interface checks
- ✅ Fluent expectation API -
On_Method(),On_Method_Any(),On_Method_Interface() - ✅ Flexible return values -
Return()for fixed values,ReturnFn()for custom logic - ✅ Built-in assertions -
Assert_Method_Called(),Assert_Method_NumberOfCalls(), etc. - ✅ Smart context handling - Automatically removes
context.Contextfrom mock setup (optional) - ✅ Generics support (Go 1.18+) - Full support for type parameters and constraints
- ✅ Complex Go types - Arrays, slices, maps, channels, structs, interfaces, function types
- ✅ Variadic parameters - Proper handling of
...Tsyntax - ✅ Import resolution - Automatic package imports and qualification
go install github.com/tim-oster/go-mock@latestRequires Go 1.18 or later.
package myservice // file: myservice.go
import "context"
type UserRepository interface {
GetUser(ctx context.Context, id string) (*User, error)
CreateUser(ctx context.Context, user *User) error
}//go:generate go-mock UserRepositorygo generate ./...This creates myservice_mock_userrepository.gen.go with a full mock implementation.
package myservice_test
import (
"testing"
"github.com/stretchr/testify/assert"
"myservice"
)
func TestUserService(t *testing.T) {
// Create mock
mockRepo := &myservice.MockUserRepository{}
// Setup expectation
expectedUser := &myservice.User{ID: "123", Name: "John"}
mockRepo.On_GetUser("123").Return(expectedUser, nil)
// Use mock in your code
service := myservice.NewUserService(mockRepo)
user, err := service.FetchUser(context.Background(), "123")
// Assert
assert.NoError(t, err)
assert.Equal(t, expectedUser, user)
mockRepo.AssertExpectations(t)
}//go:generate go-mock InterfaceName| Flag | Description | Default |
|---|---|---|
-keepctx |
Keep context.Context parameters in mock setup methods |
false |
-unexported |
Generate unexported mock struct (e.g., mockInterface instead of MockInterface) |
false |
Rename the generated mock struct:
//go:generate go-mock UserRepository:UserRepoThis generates MockUserRepo instead of MockUserRepository.
// Standard interface
//go:generate go-mock UserRepository
// Keep context in mock setup
//go:generate go-mock -keepctx APIClient
// Generate unexported mock for internal testing
//go:generate go-mock -unexported internalService
// Rename the generated mock
//go:generate go-mock UserRepository:RepoFor each interface method, go-mock generates:
// Setup with specific arguments (context auto-removed by default)
func (m *MockInterface) On_MethodName(param string) *MockInterface_MethodName_Call
// Setup with wildcard arguments (uses mock.Anything internally)
func (m *MockInterface) On_MethodName_Any() *MockInterface_MethodName_Call
// Setup with interface{} parameters for maximum flexibility
func (m *MockInterface) On_MethodName_Interface(param interface{}) *MockInterface_MethodName_Call// Set fixed return values
func (c *MockInterface_MethodName_Call) Return(s string, err error)
// Provide custom logic with a function
func (c *MockInterface_MethodName_Call) ReturnFn(fn func(string) (string, error))// Assert method was called with specific arguments
func (m *MockInterface) Assert_MethodName_Called(t *testing.T, param string)
// Assert method was called N times
func (m *MockInterface) Assert_MethodName_NumberOfCalls(t *testing.T, n int)
// Assert method was never called
func (m *MockInterface) Assert_MethodName_NotCalled(t *testing.T)By default, go-mock removes context.Context as the first parameter from mock setup methods, since context is rarely important for mocking behavior:
// Interface method
GetUser(ctx context.Context, id string) (*User, error)
// Generated setup method (context removed)
On_GetUser(id string) *MockUserRepository_GetUser_CallTo preserve context in setup methods, use -keepctx:
//go:generate go-mock -keepctx UserRepository
// Generated setup method (context kept)
On_GetUser(ctx context.Context, id string) *MockUserRepository_GetUser_Call- AST Parsing - go-mock uses Go's
go/parserto analyze your source files - Interface Extraction - Finds and filters interface definitions matching your pattern
- Code Generation - Uses jennifer to generate type-safe mock code
- Output - Creates
{source}_mock_{interface}.gen.gofiles
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.