### Basic Mock Setup Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Demonstrates the fundamental setup of a mock object using gomock.NewController and setting a single expectation with Times(1). ```go func TestBasicMock(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockRepository(ctrl) mock.EXPECT(). FindUser("123"). Return(&User{ID: "123"}, nil). Times(1) // Test code } ``` -------------------------------- ### Usage Guide Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt A guide to getting started with uber-go/mock, covering patterns and best practices. ```APIDOC ## Usage Guide ### Getting Started 1. **Installation**: `$ go install go.uber.org/mock/mockgen@latest` 2. **Generate Mocks**: Use `mockgen` to create mock implementations for your interfaces. 3. **Create Controller**: Instantiate a `gomock.Controller` in your test. 4. **Set Expectations**: Define expected method calls and their return values using `EXPECT()`. 5. **Run Code Under Test**: Execute the code that uses the mock. 6. **Verify Expectations**: Call `controller.Finish()` to ensure all expectations were met. ### Patterns and Best Practices - Keep mocks focused on the interface being tested. - Use specific argument matchers where possible for clearer tests. - Verify expectations at the end of the test using `controller.Finish()`. ``` -------------------------------- ### Basic Mock Setup Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Demonstrates the basic setup for creating a mock object, defining an expectation, and returning a value. ```APIDOC ### Basic Mock Setup ```go func TestBasicMock(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockRepository(ctrl) mock.EXPECT(). FindUser("123"). Return(&User{ID: "123"}, nil). Times(1) // Test code } ``` ``` -------------------------------- ### Go Mock Setup Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Basic setup for using Go Mock in tests. Import the library and create a mock object for your interface. ```go import "go.uber.org/mock/gomock" func TestFoo(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockMyInterface(ctrl) // Test code } ``` -------------------------------- ### Install mockgen Tool Source: https://github.com/uber-go/mock/blob/main/README.md Install the mockgen tool using the go install command. Ensure your GOPATH/bin is in your PATH. ```bash go install go.uber.org/mock/mockgen@latest ``` -------------------------------- ### Install mockgen CLI Tool Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt Use 'go install' to get the latest version of the mockgen command-line tool. ```bash $ go install go.uber.org/mock/mockgen@latest ``` -------------------------------- ### Example Type Conversion to String Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Illustrates how internal types are converted to their string representations for use in generated code. This is an internal example. ```go // In generated code, types are converted to strings: // Type representing "[]string" becomes the string "[]string" // Type representing "*os.File" becomes the string "*os.File" ``` -------------------------------- ### Index Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt Navigation guide and API surface summary for the uber-go/mock documentation. ```APIDOC ## Index ### Navigation This document serves as a central navigation point for the uber-go/mock documentation set. ### API Surface Summary Provides an overview of the main components and their relationships, including: - Core types (Controller, etc.) - API reference files (call, matchers) - Tool documentation (mockgen) - Usage and learning resources ``` -------------------------------- ### Quick Reference Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt A quick lookup guide with common patterns and code snippets for uber-go/mock. ```APIDOC ## Quick Reference ### Common Patterns - **Basic Mocking**: Generate mock, set expectation, call code, finish controller. - **Argument Matching**: Use `gomock.Any()`, `gomock.Eq()`, etc., for flexible argument checks. - **Return Values**: Chain `.Return(...)` to specify mock outputs. ### Code Snippets ```go // Example: Setting a simple expectation mockMyInterface.EXPECT().MyMethod(gomock.Any()).Return(expectedValue) // Example: Verifying expectations err := controller.Finish() if err != nil { t.Errorf("Mock verification failed: %v", err) } ``` ``` -------------------------------- ### Custom Matcher Implementation Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md An example of implementing the Matcher interface to create a custom matcher that checks if an integer is even. ```go // Custom matcher implementation type evenMatcher struct{} func (m evenMatcher) Matches(x any) bool { num, ok := x.(int) return ok && num%2 == 0 } func (m evenMatcher) String() string { return "is even" } ``` -------------------------------- ### Example: Using GotFormatterAdapter for Byte Slice Formatting Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md This example shows GotFormatterAdapter used with GotFormatterFunc to format a received byte slice into a hexadecimal string. ```go mock.EXPECT().SetBytes(gomock.GotFormatterAdapter( gomock.GotFormatterFunc(func(i any) string { b := i.([]byte) return hex.EncodeToString(b) }), gomock.Len(32), )) ``` -------------------------------- ### Verify mockgen Installation Source: https://github.com/uber-go/mock/blob/main/README.md Verify that the mockgen tool was installed correctly by checking its version. ```bash mockgen -version ``` -------------------------------- ### Setting up a Mock Expectation Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md Ensure you set up expectations using EXPECT() before calling mock methods. This example shows the correct way to set up a call to GetUser. ```go mock.EXPECT().GetUser("123").Return(&User{}, nil) user := mock.GetUser("123") ``` -------------------------------- ### Basic Test Setup with Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Demonstrates setting up a mock object and defining expectations for a method call within a Go test function. The mock is generated by mockgen and imported from a generated mocks package. ```go package mypackage_test import ( "testing" "go.uber.org/mock/gomock" "mypackage" "mypackage/mocks" // Generated mocks ) func TestMyFunction(t *testing.T) { // Setup ctrl := gomock.NewController(t) mock := mocks.NewMockDependency(ctrl) // Expectations mock.EXPECT(). Method(gomock.Any()). Return("result", nil). Times(1) // Execute obj := mypackage.NewMyType(mock) result := obj.DoWork() // Verify (automatic on test completion) if result != "expected" { t.Errorf("got %s, want expected", result) } } ``` -------------------------------- ### Package Naming with -package Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Command-line example showing how to specify a package name for the generated mocks using the -package flag. ```bash mockgen -source=foo.go -package=foo_test -destination=foo_test.go ``` -------------------------------- ### Example: Using WantFormatter for Even Number Check Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md This example demonstrates how to use WantFormatter with StringerFunc and Cond to specify that an even number is expected. ```go mock.EXPECT().SetCount(gomock.WantFormatter( gomock.StringerFunc(func() string { return "an even number" }), gomock.Cond(func(n int) bool { return n%2 == 0 }), )) ``` -------------------------------- ### Internal Interface Creation Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Shows the internal construction of an Interface type, representing the io.Reader interface and its methods. ```go // For interface io.Reader intf := &Interface{ Name: "Reader", Methods: []*Method{ // Method representing: Read(p []byte) (n int, err error) }, } ``` -------------------------------- ### Internal Parameter Example (Slice Type) Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Illustrates the internal construction of a Parameter type for a slice, specifically for a byte slice. ```go // For parameter: p []byte param := &Parameter{ Name: "p", Type: sliceType{elem: builtinType{name: "byte"}}, } ``` -------------------------------- ### Usage of TestReporter Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Example of creating a gomock controller with a testing.T instance, which implements TestReporter. ```go ctrl := gomock.NewController(t) // t is a TestReporter ``` -------------------------------- ### Example Matcher Implementation Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Custom implementation of the Matcher interface to check if an integer is within a specified range. ```go type rangeM struct { min, max int } func (m rangeM) Matches(x any) bool { val, ok := x.(int) return ok && val >= m.min && val <= m.max } func (m rangeM) String() string { return fmt.Sprintf("is between %d and %d", m.min, m.max) } func InRange(min, max int) gomock.Matcher { return rangeM{min, max} } ``` -------------------------------- ### Internal Method Construction Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Demonstrates the internal construction of a Method type, representing the Read method with its parameters and return values. ```go // For method: func (r Reader) Read(p []byte) (n int, err error) method := &Method{ Name: "Read", In: []*Parameter{ &Parameter{Name: "p", Type: ...}, // []byte }, Out: []*Parameter{ &Parameter{Name: "n", Type: ...}, // int &Parameter{Name: "err", Type: ...}, // error }, } ``` -------------------------------- ### Manual Finish Example - Go Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Demonstrates manual invocation of Finish() for verifying mock expectations. Ensure Finish() is called to avoid test failures due to unsatisfied expectations. ```go func TestManualFinish(t *testing.T) { ctrl := gomock.NewController(&customReporter{t: t}) defer ctrl.Finish() mockObj := NewMockInterface(ctrl) mockObj.EXPECT().SomeMethod() // If SomeMethod is not called, Finish() fails the test } ``` -------------------------------- ### Internal Package Parsing Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Illustrates the internal usage of the Package type for parsing a Go package and iterating over its interfaces. ```go // Used by mockgen internally pkg := parsePackage("github.com/user/repo/storage") for _, intf := range pkg.Interfaces { // Generate mock for each interface } ``` -------------------------------- ### Flexible Expectation Matching Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Illustrates how to use `gomock.Any()` for flexible argument matching and `DoAndReturn` for custom logic within expectations. ```APIDOC ### Flexible Expectation Matching ```go func TestFlexibleMatching(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockHandler(ctrl) mock.EXPECT(). Handle(gomock.Any()). DoAndReturn(func(req interface{}) interface{} { // Custom logic return nil }). AnyTimes() // Test code } ``` ``` -------------------------------- ### Go Generate Example: Mock Generation Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Use the go generate command with the mockgen tool to automatically generate mock implementations for your interfaces. This command should be placed as a comment in your Go source file. ```go package mypackage //go:generate mockgen -source=interfaces.go -destination=mocks/mock_interfaces.go -package=mocks type MyInterface interface { DoSomething(string) error } ``` ```bash go generate ./... ``` -------------------------------- ### Check mockgen Version Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Run this command to check the installed version of mockgen. ```bash # Check mockgen version mockgen -version ``` -------------------------------- ### Type String Representation Examples Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Illustrates how different type representations are converted to their string form. The String method requires a map of package imports and an optional package override. ```go intType.String(map[string]string{}, "") // "int" pointerUserType.String(m, "") // "*User" or "*pkg.User" depending on imports ``` -------------------------------- ### Multiple Calls with Call Order Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Shows how to enforce the order of mock method calls using the After method, ensuring one call happens after another. ```go func TestCallOrder(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockService(ctrl) firstCall := mock.EXPECT().Initialize() mock.EXPECT().Process().After(firstCall) // Test code } ``` -------------------------------- ### Specify Destination with -destination Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Command-line example demonstrating the use of the -destination flag to specify the output file for generated mocks. ```bash mockgen -source=foo.go -destination=mocks/foo.go ``` -------------------------------- ### Usage of ControllerOption Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Example of creating a gomock controller with an option, specifically WithOverridableExpectations, which allows later expectations to override earlier ones. ```go ctrl := gomock.NewController(t, gomock.WithOverridableExpectations()) ``` -------------------------------- ### Example Error Message in gomock/callset Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-callset.md This example demonstrates the detailed error message generated by callSet when an unexpected call is made to a mocked method. It highlights mismatches in arguments and expected values. ```go Unexpected call to *MockService.GetUser("unknown") because: expected call at example_test.go:42 has the wrong number of arguments expected call at example_test.go:45 doesn't match the argument at index 0 Got: "unknown" Want: "123" ``` -------------------------------- ### Multiple Calls with Call Order Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Shows how to define expectations for multiple calls and enforce a specific order using the `After` method. ```APIDOC ### Multiple Calls with Call Order ```go func TestCallOrder(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockService(ctrl) firstCall := mock.EXPECT().Initialize() mock.EXPECT().Process().After(firstCall) // Test code } ``` ``` -------------------------------- ### Internal Parameter Example (Unnamed Return) Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Shows the internal construction of a Parameter type for an unnamed return value, such as an integer or error. ```go // For unnamed return: (int, error) param1 := &Parameter{ Name: "", // Unnamed Type: builtinType{name: "int"}, } ``` -------------------------------- ### Usage of GotFormatterFunc Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Example of creating a GotFormatterFunc to format received values in a specific way for mock error messages. ```go gomock.GotFormatterFunc(func(i any) string { return fmt.Sprintf("value: %v", i) }) ``` -------------------------------- ### Generate Mocks using Package Mode (Import Path) Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Generates mocks from an installed package using its import path. This is the default mode. ```bash mockgen database/sql/driver Conn,Driver ``` -------------------------------- ### Usage with GotFormatterAdapter Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Example of using GotFormatterAdapter to format received values in mock expectations, here formatting an integer as hexadecimal. ```go mock.EXPECT().SetValue(gomock.GotFormatterAdapter( gomock.GotFormatterFunc(func(i any) string { return fmt.Sprintf("0x%x", i) }), gomock.Eq(255), )) ``` -------------------------------- ### Handling Multiple Calls with Times() Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md If a mock method is expected to be called multiple times, use Times() with the appropriate count. This example shows how to correctly set up a method expected to be called twice. ```go mock.EXPECT(). Initialize(). Times(2) mock.Initialize() mock.Initialize() ``` -------------------------------- ### Generated Mock Structure Example Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Illustrates the typical structure of a mock generated by mockgen for a given Go interface, including the mock struct, constructor, EXPECT method, and recorder methods. ```go type Service interface { GetValue(ctx context.Context) (int, error) SetValue(ctx context.Context, val int) error } ``` ```go type MockService struct { ctrl *gomock.Controller } func NewMockService(ctrl *gomock.Controller) *MockService func (m *MockService) EXPECT() *MockServiceMockRecorder func (m *MockService) GetValue(ctx context.Context) (int, error) func (m *MockService) SetValue(ctx context.Context, val int) error type MockServiceMockRecorder struct { mock *MockService } func (mr *MockServiceMockRecorder) GetValue(ctx any) *gomock.Call func (mr *MockServiceMockRecorder) SetValue(ctx any, val any) *gomock.Call ``` -------------------------------- ### Check Satisfaction Example - Go Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Illustrates using the Satisfied() method to check the state of mock expectations. This is useful for verifying that calls have been made as expected before or after certain operations. ```go func TestCheckSatisfaction(t *testing.T) { ctrl := gomock.NewController(t) m := NewMockInterface(ctrl) m.EXPECT().Method1() m.EXPECT().Method2() if ctrl.Satisfied() { t.Fatal("expectations not yet satisfied") } m.Method1() m.Method2() if !ctrl.Satisfied() { t.Fatal("expectations should now be satisfied") } } ``` -------------------------------- ### Get Needed Imports Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Returns a map of package paths that are required for the generated mock. Use this to ensure all necessary dependencies are imported. ```go pkg.Imports() // Returns map[string]bool of needed imports // e.g., map[string]bool{ // "io": true, // "database/sql": true, // "github.com/user/pkg": true, // } ``` -------------------------------- ### Verify Expectations Met with gomock Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Example of setting expectations on a mock object and how the test fails if not all expected methods are called. This is automatic with testing.T in Go 1.14+. ```go func TestComplete(t *testing.T) { ctrl := gomock.NewController(t) mock := mocks.NewMockService(ctrl) mock.EXPECT().Initialize() mock.EXPECT().Process() // If not all called, Finish() fails the test // (Automatic with testing.T in Go 1.14+) } ``` -------------------------------- ### Handling Nil Returns for Non-Nillable Types Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md Avoid returning nil for types that cannot be nil (like int). For non-nillable types, return their zero value. This example shows the correct way to return for GetCount. ```go mock.EXPECT(). GetCount(). Return(0) ``` -------------------------------- ### Setting Up a Test Controller and Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/INDEX.md Initialize a gomock controller and create a mock object for an interface. This is the first step in setting up mocks for testing. ```go ctrl := gomock.NewController(t) mock := NewMockInterface(ctrl) ``` -------------------------------- ### Create and Use a Mock Object Source: https://github.com/uber-go/mock/blob/main/README.md Demonstrates how to create a mock object for the Foo interface and set expectations for its methods. Use this when you need to assert that specific method calls are made with expected arguments. ```go func TestFoo(t *testing.T) { ctrl := gomock.NewController(t) m := NewMockFoo(ctrl) // Asserts that the first and only call to Bar() is passed 99. // Anything else will fail. m. EXPECT(). Bar(gomock.Eq(99)). Return(101) SUT(m) } ``` -------------------------------- ### Run Sample Package Test Source: https://github.com/uber-go/mock/blob/main/sample/README.md Execute the tests for the sample package using Go. This command will run the tests and verify the mock generation and usage. ```bash go test go.uber.org/mock/sample ``` -------------------------------- ### Organize Mocks Directory Structure Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Illustrates a typical directory structure for organizing mock files within a Go project. ```go mypackage/ ├── service.go ├── repository.go └── mocks/ ├── mock_service.go ├── mock_repository.go └── generate.go // Contains //go:generate directives ``` -------------------------------- ### Use go:generate for Mock Creation Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Demonstrates how to use //go:generate directives in a Go file to automatically generate mock implementations for interfaces. ```go // mocks/generate.go package mocks //go:generate mockgen -source=../service.go -destination=mock_service.go -package=mocks //go:generate mockgen -source=../repository.go -destination=mock_repository.go -package=mocks ``` -------------------------------- ### Usage of StringerFunc Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Example showing how StringerFunc can be used with gomock.WantFormatter to provide a custom string representation for a matcher. ```go gomock.WantFormatter( gomock.StringerFunc(func() string { return "a prime number" }), gomock.Cond(func(n int) bool { return isPrime(n) }), ) ``` -------------------------------- ### Create and Use a Stub Object Source: https://github.com/uber-go/mock/blob/main/README.md Demonstrates how to create a stub object for the Foo interface and define its behavior using DoAndReturn and AnyTimes. Use this when you need to control the return values or side effects of method calls without strict assertion. ```go func TestFoo(t *testing.T) { ctrl := gomock.NewController(t) m := NewMockFoo(ctrl) // Does not make any assertions. Executes the anonymous functions and returns // its result when Bar is invoked with 99. m. EXPECT(). Bar(gomock.Eq(99)). DoAndReturn(func(_ int) int { time.Sleep(1*time.Second) return 101 }). AnyTimes() // Does not make any assertions. Returns 103 when Bar is invoked with 101. m. EXPECT(). Bar(gomock.Eq(101)). Return(103). AnyTimes() SUT(m) } ``` -------------------------------- ### Prerequisite Calls in Go Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-callset.md Illustrates setting up prerequisite calls using `Call.After()`. This ensures that a specific call is only matched after its prerequisites have been satisfied, enforcing a sequence of operations. ```go init := mock.EXPECT().Initialize() process := mock.EXPECT().Process().After(init) // At this point: // - init call can be matched // - process cannot be matched until init is satisfied mock.Initialize() // Satisfy init // Now: // - init is satisfied and prerequisite is dropped // - process can be matched ``` -------------------------------- ### Type Safety with -typed Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Command-line example illustrating the use of the -typed flag to enable type-safe mock generation. ```bash mockgen -source=interfaces.go -typed -destination=mocks/mocks.go ``` -------------------------------- ### Import Runtime Library Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Import the runtime library for go-mock. The mockgen executable is a separate tool. ```go import "go.uber.org/mock/gomock" // Runtime library // mockgen executable is go.uber.org/mock/mockgen ``` -------------------------------- ### Any Matcher Usage Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md Demonstrates using the Any matcher to accept any value for a mocked method parameter. ```go mock.EXPECT(). Process(gomock.Any()). Return(nil) ``` -------------------------------- ### Debug Parse Errors Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Use the -debug_parser flag to get detailed output for debugging parsing errors in your interface definitions. ```bash # Debug parse errors mockgen -source=interfaces.go -debug_parser ``` -------------------------------- ### Type Interface Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md The Type interface represents any Go type and provides methods to get its string representation and manage imports. ```APIDOC ## Type Interface An interface representing any Go type. ```go type Type interface { String(pm map[string]string, pkgOverride string) string addImports(im map[string]bool) } ``` ### Methods: - `String(pm map[string]string, pkgOverride string) string` — Returns the string representation of the type - `pm` — A map of package import paths to their local names - `pkgOverride` — A package path to exclude from the output (used to avoid self-references) - Returns the type as it would appear in Go code - `addImports(im map[string]bool)` — Adds all import paths needed for this type to the map ### Implementations: The Type interface is implemented by various internal types: - **builtinType** — Built-in types (int, string, bool, error, etc.) - **namedType** — Named types (User, Reader, Writer, etc.) - **pointerType** — Pointer types (*int, *User, etc.) - **sliceType** — Slice types ([]int, []string, etc.) - **arrayType** — Array types ([3]int, [10]string, etc.) - **mapType** — Map types (map[string]int, etc.) - **chanType** — Channel types (chan int, <-chan string, chan<- bool, etc.) - **funcType** — Function types (func(int) string, etc.) - **interfaceType** — Interface types (io.Reader, fmt.Stringer, etc.) - **typeParam** — Generic type parameters (T, U, etc.) ``` -------------------------------- ### Eq Matcher Usage Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md Shows how to use the Eq matcher to assert equality for string, integer, and struct parameters. ```go mock.EXPECT().SetName(gomock.Eq("Alice")) mock.EXPECT().SetCount(gomock.Eq(42)) mock.EXPECT().SetUser(gomock.Eq(&User{ID: "123", Name: "Alice"})) ``` -------------------------------- ### Recommended Project Structure for Uber Go Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/INDEX.md Illustrates the standard directory layout for organizing interfaces, implementations, tests, and generated mocks within a project using go.uber.org/mock. ```go mypackage/ ├── interfaces.go // Interfaces to mock ├── service.go // Implementations ├── service_test.go // Tests using mocks └── mocks/ ├── generate.go // //go:generate directives ├── mock_service.go // Generated mocks └── mock_repository.go ``` -------------------------------- ### NewController Basic Usage Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Creates a new Controller for managing mock expectations. In Go 1.14+, no explicit ctrl.Finish() is needed as cleanup is automatic. ```go func TestUserService(t *testing.T) { ctrl := gomock.NewController(t) // No explicit ctrl.Finish() needed in Go 1.14+ mockRepository := NewMockUserRepository(ctrl) mockRepository.EXPECT().GetUser("user1").Return(&User{ID: "user1", Name: "Alice"}, nil) // Test code using mockRepository } ``` -------------------------------- ### String and Regex Matching in Go Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Covers various ways to match string arguments in mock expectations, including exact string matches, regular expressions, and matching any string. ```go // Exact string match mockHandler.EXPECT(). SetFormat("json") // Regex pattern mockValidator.EXPECT(). ValidateEmail(gomock.Regex(`^[^@]+@[^@]+\.[a-z]{2,}$`)) // Any string mockLogger.EXPECT(). Log(gomock.Any()) ``` -------------------------------- ### Generating Mocks with mockgen Command Source: https://github.com/uber-go/mock/blob/main/_autodocs/INDEX.md Use the `mockgen` command-line tool to generate mock implementations for Go interfaces. Specify the source interface file and the output destination. ```bash mockgen -source=interfaces.go -destination=mocks/mocks.go ``` -------------------------------- ### Write Test Using Generated Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Demonstrates how to use a generated mock in a Go test. It sets up a gomock controller, creates a mock repository, defines an expectation for the GetUser method, and then calls the mock method. ```go // user_test.go package service_test import ( "testing" "github.com/user/pkg/mocks" "go.uber.org/mock/gomock" ) func TestGetUser(t *testing.T) { // Create controller ctrl := gomock.NewController(t) // Create mock mockRepo := mocks.NewMockUserRepository(ctrl) // Set expectations mockRepo.EXPECT(). GetUser("123"). Return(&User{ID: "123", Name: "Alice"}, nil). Times(1) // Use the mock user, err := mockRepo.GetUser("123") // Assertions (gomock verifies expectations automatically) if err != nil || user.Name != "Alice" { t.Fail() } } ``` -------------------------------- ### Insufficient Calls Error in gomock Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md When using MinTimes(n), ensure the method is called at least 'n' times. This example shows setting MinTimes(3) and calling the method only once. ```go // Wrong - MinTimes(3) but only called once mock.EXPECT(). Info(gomock.Any()). MinTimes(3) mock.Info("msg") // Only once! // Correct mock.EXPECT(). Info(gomock.Any()). MinTimes(3) mock.Info("msg1") mock.Info("msg2") mock.Info("msg3") // Called 3 times ``` -------------------------------- ### Flexible Expectation Matching with Any() and DoAndReturn() Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Illustrates flexible expectation matching using gomock.Any() for any argument and DoAndReturn() for custom logic, allowing the mock to be called any number of times. ```go func TestFlexibleMatching(t *testing.T) { ctrl := gomock.NewController(t) mock := NewMockHandler(ctrl) mock.EXPECT(). Handle(gomock.Any()). DoAndReturn(func(req interface{}) interface{} { // Custom logic return nil }). AnyTimes() // Test code } ``` -------------------------------- ### Using Argument Matchers for Type Safety Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md Use argument matchers like gomock.Any() when the exact value is not critical or when dealing with type mismatches. This example allows any string argument for GetUser. ```go mock.EXPECT(). GetUser(gomock.Any()). Return(&User{}, nil) user := mock.GetUser("456") ``` -------------------------------- ### Mockgen Model Import Path Handling Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Illustrates how the mockgen model handles different import path scenarios, including blank imports (import .) and renamed imports (import alias "path"). It also notes that types in the same package do not require qualification. ```go // Blank imports (import .) pkg.DotImports // []string{"fmt"} // Renamed imports (import alias "path") pm := map[string]string{"alias": "actual/path"} // Package-local types // Types in the same package as output don't need qualification ``` -------------------------------- ### Handle Variadic Methods with Mocking Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Mock variadic methods by providing matchers for the fixed arguments and using `gomock.Eq` or other matchers for the variadic part. The `Do` function receives the arguments as they would be passed to the real method. ```go // For func Log(format string, args ...any) mock.EXPECT(). Log("%d", gomock.Eq(42)). Do(func(format string, nums ...int) { // nums contains the variadic args }) ``` -------------------------------- ### Matching Return Value Types Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md The types of values returned by Return() must be assignable to the method's return types. This example corrects a GetCount call returning a string to one returning an int. ```go mock.EXPECT(). GetCount(). Return(42) ``` -------------------------------- ### Allowing Nil Returns for Nillable Types Source: https://github.com/uber-go/mock/blob/main/_autodocs/errors.md For methods returning nillable types (pointers, interfaces, slices, maps, channels), returning nil is permissible. This example shows a correct nil return for a (*User, error) signature. ```go mock.EXPECT(). GetUser(). Return(nil, nil) ``` -------------------------------- ### Regex Matcher Usage Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md Illustrates using the Regex matcher to validate strings or byte slices against regular expression patterns. ```go mock.EXPECT().ValidateEmail(gomock.Regex(`^[a-z0-9]+@[a-z]+\.[a-z]+$`)) mock.EXPECT().MatchVersion(gomock.Regex(`^v\d+\.\d+\.\d+$`)) mock.EXPECT().CheckPath(gomock.Regex(`^/api/v[12]/.*`)) ``` -------------------------------- ### Matching Arguments with Eq and Any Source: https://github.com/uber-go/mock/blob/main/_autodocs/INDEX.md Use gomock matchers like `Eq` for exact value matching and `Any` for any value matching when setting expectations on mock methods. ```go mock.EXPECT().Method(gomock.Eq(value)) ``` ```go mock.EXPECT().Method(gomock.Any()) ``` -------------------------------- ### Specify Package Name Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Use the -package flag to define the package name for the generated mock code. The default is a 'mock_' prefix followed by the source package name. ```bash mockgen -source=foo.go -package=foo_mocks ``` -------------------------------- ### API Reference - Call Expectations Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt Details on setting up call expectations, return values, and call ordering for mocks. ```APIDOC ## Call Expectations ### Description Defines how mock methods should be called, what they should return, and in what order. ### Setting Expectations Use the `EXPECT()` method on a mock object to start defining expectations. ### Returns Specify return values for mock method calls using `.Return()`. ### Ordering Control the order of mock calls using methods like `.Times()` and `.After()`. ``` -------------------------------- ### Execute an Action for a Mock Call Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-call.md Use the Do method to specify a function to execute when a mock call matches. The function's return values are ignored. The function must have the same parameter types as the mocked method and is called with the actual arguments. ```go mockLogger.EXPECT(). Log(gomock.Any()). Do(func(msg string) { fmt.Println("Logged:", msg) }) mockMutex.EXPECT(). Lock(). Do(func() { // Simulate lock acquisition }) mockRepository.EXPECT(). Save(gomock.Any()). Do(func(user *User) { user.UpdatedAt = time.Now() }) ``` -------------------------------- ### Basic Expectation with Return Value in Go Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Define a simple expectation for a method call and specify its return values. This is the most basic form of setting up a mock. ```go mockRepo.EXPECT(). GetUser("123"). Return(&User{ID: "123"}, nil) user, _ := mockRepo.GetUser("123") ``` -------------------------------- ### Build Package to Archive and Generate Mock Source: https://github.com/uber-go/mock/blob/main/README.md Use archive mode to generate mocks from a package archive file (.a). This requires building the package to an archive first, then specifying the archive file and the interfaces to mock. ```bash # Build the package to a archive. go build -o pkg.a database/sql/driver mockgen -archive=pkg.a database/sql/driver Conn,Driver ``` -------------------------------- ### Chain Call Methods Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-call.md Chain Call methods like Return, Times, Do, DoAndReturn, MinTimes, MaxTimes, and AnyTimes for flexible mock configuration. All Call methods return *Call to enable chaining. ```go mockRepository.EXPECT(). GetUser("123"). Return(&User{ID: "123"}, nil). Times(1) ``` ```go mockHandler.EXPECT(). Handle(gomock.Any()). Do(func(req Request) { fmt.Println("Handling:", req) }). Return(Response{Status: "OK"}). MinTimes(1). MaxTimes(3) ``` ```go mockService.EXPECT(). Query(gomock.Any(), gomock.Any()). DoAndReturn(func(ctx context.Context, q string) ([]string, error) { if ctx.Err() != nil { return nil, ctx.Err() } return []string{"result1", "result2"}, nil }). AnyTimes() ``` -------------------------------- ### Accepting Any Argument with gomock.Any Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md Use gomock.Any to indicate that any argument is acceptable for a given parameter. This is useful when the specific value of an argument does not affect the test outcome. ```go mock.EXPECT().Log(gomock.Any()) ``` -------------------------------- ### Use Pre-serialized Model Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Use the -model_gob flag to skip package/source loading and use a pre-serialized model package from a gob file. This is an advanced option for performance optimization. ```bash mockgen -model_gob=model.gob ``` -------------------------------- ### Match Arguments with Exact Values, AnyOf, Cond, and All Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Specify argument matching criteria. Use exact values for precise matching, `gomock.AnyOf` for multiple allowed values, `gomock.Cond` for custom conditional logic, and `gomock.All` to combine multiple matchers. ```go // Exact value mock.EXPECT().SetName("Alice") // Multiple options mock.EXPECT().SetStatus(gomock.AnyOf("active", "inactive")) // Conditional mock.EXPECT().SetValue(gomock.Cond(func(v int) bool { return v > 0 })) // Complex: non-nil AND even mock.EXPECT().Process(gomock.All( gomock.Not(gomock.Nil()), gomock.Cond(func(n int) bool { return n%2 == 0 }), )) ``` -------------------------------- ### Generate Mocks using Source Mode Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Generates mocks from a single Go source file. Use this when you have the interface definition in a .go file. ```bash mockgen -source=foo.go ``` -------------------------------- ### View Generated Mock Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Use this command to view the content of the generated mock file, typically located in the mocks/ directory. ```bash # View generated mock (usually in mocks/ directory) cat mocks/mock_interfaces.go ``` -------------------------------- ### Source Mode Input Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Use the -source flag to specify a source file for mock generation in source mode. The import path is derived from this file. ```bash mockgen -source=interfaces.go [other options] ``` -------------------------------- ### Checking Mock Satisfaction in Go Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Illustrates how to check if all mock expectations have been met without immediately failing the test. This allows for custom handling of unmet expectations. ```go if !ctrl.Satisfied() { // Handle unmet expectations without failing the test immediately fmt.Println("Not all expectations were met") } ``` -------------------------------- ### Tool Documentation - mockgen Command Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt Documentation for the mockgen command-line tool, including its flags, modes, and usage. ```APIDOC ## mockgen Command ### Description A command-line tool used to generate mock implementations for Go interfaces. ### Usage `mockgen [flags] ` ### Flags - `--source`: Specify the source file(s) to generate mocks from. - `--destination`: Output file for the generated mocks. - `--package`: Package name for the generated mocks. - `--build-tags`: Build tags to include in the generated file. - `--imports`: Comma-separated list of imports to include. - `--mock_names`: Map interface names to mock names. - `--delegate_to`: Generate mocks that delegate to a real object. - `--self_test_package`: Generate mocks for the test package itself. - `--aux_files`: Additional files to consider for type information. - `--exclude_fields`: Fields to exclude from generated mocks. - `--exclude_methods`: Methods to exclude from generated mocks. - `--output_dir`: Directory to write generated files to. - `--output_file`: Specific file to write generated mocks to. - `--output_stdout`: Write generated mocks to stdout. - `--output_format`: Output format (e.g., go, json). - `--mode`: Generation mode (e.g., interface, struct). - `--help`: Display help message. - `--version`: Display version information. ``` -------------------------------- ### Integrating Mock Generation with go:generate Source: https://github.com/uber-go/mock/blob/main/_autodocs/INDEX.md Include `//go:generate` directives in your Go source files to automatically generate mocks during the build process. ```go //go:generate mockgen -source=interfaces.go -destination=mocks/mocks.go ``` -------------------------------- ### Len Matcher Usage Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md Shows how to use the Len matcher to assert the length of slices, strings, maps, or channels. ```go mock.EXPECT().ProcessSlice(gomock.Len(3)) mock.EXPECT().HandleString(gomock.Len(10)) mock.EXPECT().IterateMap(gomock.Len(0)) // empty map ``` -------------------------------- ### Nil Matcher Usage Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-matchers.md Illustrates using the Nil matcher to explicitly expect nil values for return values or parameters. ```go mock.EXPECT().GetValue().Return(nil, nil) mock.EXPECT().Process(gomock.Nil()).Return(nil) mock.EXPECT().GetChannel().Return(gomock.Nil()) ``` -------------------------------- ### Usage of TestHelper Interface Source: https://github.com/uber-go/mock/blob/main/_autodocs/types.md Demonstrates marking a function as a test helper using t.Helper() within a function that accepts a gomock.TestHelper. ```go func MyTestHelper(t gomock.TestHelper) { t.Helper() // Mark this function as a helper // Test code } ``` -------------------------------- ### Expectation with Argument Matching and Action Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-call.md Set an expectation for a method with specific argument matching and a custom action. Use `gomock.Eq` for exact matches and `Do` to execute custom logic. ```go mock.EXPECT(). Process(gomock.Eq("important")). Do(func(s string) { log.Printf("Processing: %s", s) }). Return(nil). Times(1) ``` -------------------------------- ### Mock Generation with Build Tags Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Generates mocks while considering specific build tags. Use the `-build_flags` option to pass build tags to the Go toolchain during mock generation. ```bash mockgen -source=interfaces.go -build_flags="-tags=integration" -destination=mocks/mocks.go ``` -------------------------------- ### Go Mock Actions Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Define actions to perform when a mocked method is called. This includes running functions, returning values from functions, and modifying arguments. ```go // Run function, ignore return .Do(func(args...) { ... }) // Run function, use its return .DoAndReturn(func(args...) returnType { ... }) // Modify pointer argument .SetArg(0, value) ``` -------------------------------- ### Running Custom Logic with Do and DoAndReturn Source: https://github.com/uber-go/mock/blob/main/_autodocs/INDEX.md Execute custom logic or return specific values when a mock method is called using `Do` for side effects and `DoAndReturn` for custom return values. ```go .Do(func(...) { /* logic */ }) ``` ```go .DoAndReturn(func(...) returnType { /* return */ }) ``` -------------------------------- ### Archive Mode Input Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Use the -archive flag to specify a package archive file (.a) for mock generation in archive mode. This flag is followed by the import path and interface names. ```bash mockgen -archive=pkg.a package/path Interface1,Interface2 ``` -------------------------------- ### Generate Mock from Source File Source: https://github.com/uber-go/mock/blob/main/README.md Use source mode to generate mocks directly from a Go source file. This mode is enabled with the -source flag and can optionally use -imports and -aux_files for more complex scenarios. ```bash mockgen -source=foo.go [other options] ``` -------------------------------- ### Controller Options: WithContext Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Use WithContext to associate a context with the controller. The provided test context will be cancelled if any Fatalf occurs, helping to manage test lifecycles. ```go ctx := context.Background() ctrl, testCtx := gomock.WithContext(ctx, t) mock := NewMockService(ctrl) // testCtx is cancelled if any Fatalf occurs ``` -------------------------------- ### Generate Mock from Package Source: https://github.com/uber-go/mock/blob/main/README.md Use package mode to generate mocks by specifying the package import path and interface names. This is convenient for use with `go:generate` directives. ```bash mockgen database/sql/driver Conn,Driver # Convenient for `go:generate`. mockgen . Conn,Driver ``` -------------------------------- ### Name Mocks Descriptively with mockgen Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Shows how to use the -mock_names flag with mockgen to provide custom names for generated mocks, improving clarity. ```bash mockgen -source=interfaces.go -mock_names=Repository=InMemoryRepository,Cache=NoOpCache ``` -------------------------------- ### WithContext Source: https://github.com/uber-go/mock/blob/main/_autodocs/api-reference-controller.md Creates a new Controller and returns a context that is cancelled on any fatal failure, allowing for early termination of goroutines listening to the context. ```APIDOC ## WithContext ### Description Creates a new Controller and returns a context that is cancelled on any fatal failure. This is useful for coordinating test cleanup and signaling cancellation to background goroutines. ### Function Signature ```go func WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) ``` ### Parameters #### Path Parameters - **ctx** (context.Context) - Required - The parent context to derive from. - **t** (TestReporter) - Required - The test reporter for failure reports. ### Returns - **&Controller** - A new `*Controller`. - **context.Context** - A context that is cancelled if any fatal failure occurs in the test. ### Example ```go func TestWithCancellation(t *testing.T) { ctx := context.Background() ctrl, testCtx := gomock.WithContext(ctx, t) mockService := NewMockService(ctrl) // If any Fatalf is called, testCtx is cancelled go func() { <-testCtx.Done() // Handle cancellation }() } ``` ``` -------------------------------- ### Run Concurrent Mock Test Source: https://github.com/uber-go/mock/blob/main/sample/concurrent/README.md Execute the concurrent mock test using the Go testing tool with the race detector enabled. ```bash go test -race go.uber.org/mock/sample/concurrent ``` -------------------------------- ### Print Model Output Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-model.md Provides a debug-friendly string representation of the parsed package, interface, and method details. Useful for understanding the internal model structure. ```text package sql interface Conn - method Begin in: - ctx: context.Context out: - error ``` -------------------------------- ### Common Mistake: No Argument Matcher Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md When specifying expectations, if no argument matchers are provided, the mock will expect exactly nil arguments. Provide matchers for non-nil arguments. ```go // Wrong - no argument matcher mock.EXPECT().GetUser() // Expects exactly nil argument mock.GetUser("123") // Fails - argument mismatch ``` -------------------------------- ### Run go generate Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Executes go generate commands, which in this context will run the mockgen directive to create mock files. ```bash go generate ./... ``` -------------------------------- ### Generate Mocks using Package Mode (Current Package) Source: https://github.com/uber-go/mock/blob/main/_autodocs/mockgen-command.md Generates mocks from interfaces defined in the current package. Use '.' to specify the current directory. ```bash mockgen . MyInterface ``` -------------------------------- ### API Reference - Controller Source: https://github.com/uber-go/mock/blob/main/_autodocs/MANIFEST.txt Documentation for the Controller type, its lifecycle, and configuration options. ```APIDOC ## Controller Type ### Description Provides control over mock object lifecycles and expectation verification. ### Usage Typically created once per test case to manage mock objects and their expectations. ### Configuration Options for configuring controller behavior, such as strictness and timeouts. ``` -------------------------------- ### Add go:generate Directive for Mock Generation Source: https://github.com/uber-go/mock/blob/main/_autodocs/usage-guide.md Adds a go:generate directive to a Go file. Running 'go generate ./...' will execute the mockgen command to create the mock implementation. ```go //go:generate mockgen -source=user.go -destination=mocks/mock_user.go -package=mocks ``` -------------------------------- ### Mock Method with Dynamic Return Based on Input Source: https://github.com/uber-go/mock/blob/main/_autodocs/quick-reference.md Simulate variable return values or errors based on specific input arguments using DoAndReturn. This is helpful for testing scenarios with different data states or edge cases. ```go mock.EXPECT(). Fetch(gomock.Any()). DoAndReturn(func(id string) (*Record, error) { if id == "missing" { return nil, errors.New("not found") } return &Record{ID: id}, nil }). AnyTimes() ```