Convert Figma logo to code with AI

golang logomock

GoMock is a mocking framework for the Go programming language.

9,298
609
9,298
81

Top Related Projects

5,959

A mock code autogenerator for Go

22,996

A toolkit with common assertions and mocks that plays nicely with the standard library

HTTP mocking for Golang

2,079

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽

3,339

Monkey patching in Go

Quick Overview

GoMock is a mocking framework for the Go programming language. It provides a flexible and easy-to-use system for creating mock objects in unit tests, allowing developers to isolate and test specific components of their code without relying on external dependencies.

Pros

  • Easy integration with Go's built-in testing framework
  • Supports method stubbing with customizable return values and behaviors
  • Provides a code generation tool (mockgen) to automatically create mock implementations
  • Allows for precise control over method call expectations and verifications

Cons

  • Learning curve for new users, especially those unfamiliar with mocking concepts
  • Can lead to overly complex test setups if not used judiciously
  • May encourage excessive mocking, potentially reducing the effectiveness of integration tests

Code Examples

  1. Creating a mock object:
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockObj := mock_package.NewMockInterface(ctrl)
  1. Setting up expectations:
mockObj.EXPECT().
    SomeMethod(gomock.Any()).
    Return(42).
    Times(1)
  1. Using the mock in a test:
result := mockObj.SomeMethod("input")
if result != 42 {
    t.Errorf("Expected 42, got %d", result)
}

Getting Started

  1. Install GoMock:
go get github.com/golang/mock/mockgen@v1.6.0
  1. Generate a mock for your interface:
mockgen -source=path/to/interface.go -destination=path/to/mock_interface.go -package=mock_package
  1. Use the generated mock in your tests:
import (
    "testing"
    "github.com/golang/mock/gomock"
    "path/to/mock_package"
)

func TestSomething(t *testing.T) {
    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    mockObj := mock_package.NewMockInterface(ctrl)
    // Set up expectations and run your test
}

Competitor Comparisons

5,959

A mock code autogenerator for Go

Pros of mockery

  • Generates mock implementations for entire interfaces automatically
  • Supports generating mocks for external packages without modifying source code
  • Offers a command-line tool for easy integration into build processes

Cons of mockery

  • Requires an additional tool installation and setup
  • May generate more code than necessary for simple mocking scenarios
  • Learning curve for configuring and customizing mock generation

Code Comparison

mockery:

//go:generate mockery --name=Repository
type Repository interface {
    GetUser(id int) (*User, error)
}

mock:

type MockRepository struct {
    mock.Mock
}

func (m *MockRepository) GetUser(id int) (*User, error) {
    args := m.Called(id)
    return args.Get(0).(*User), args.Error(1)
}

mockery automatically generates mock implementations, while mock requires manual implementation of mock methods. mockery's approach can save time and reduce boilerplate code, especially for larger interfaces. However, mock provides more fine-grained control over mock behavior and may be preferred for simpler use cases or when custom mock logic is required.

Both tools have their strengths and are widely used in the Go community. The choice between them often depends on project requirements, team preferences, and the complexity of the interfaces being mocked.

22,996

A toolkit with common assertions and mocks that plays nicely with the standard library

Pros of testify

  • More comprehensive testing toolkit with assertions, mocks, and suite support
  • Easier to write readable and expressive tests with fluent assertion methods
  • Better integration with Go's built-in testing package

Cons of testify

  • Larger dependency with more code to maintain
  • Slightly steeper learning curve due to more features and options

Code Comparison

testify:

assert := assert.New(t)
assert.Equal(expected, actual, "they should be equal")
assert.NotNil(object)
mock := new(MyMockedObject)
mock.On("DoSomething", 123).Return(true, nil)

mock:

ctrl := gomock.NewController(t)
defer ctrl.Finish()
mock := NewMockMyInterface(ctrl)
mock.EXPECT().DoSomething(123).Return(true, nil)

Summary

testify offers a more comprehensive testing toolkit with easier-to-read assertions and better integration with Go's testing package. However, it comes with a larger codebase and slightly steeper learning curve. mock focuses specifically on mocking, providing a more lightweight solution for that particular use case. The choice between the two depends on whether you need a full-featured testing toolkit or a dedicated mocking library.

HTTP mocking for Golang

Pros of httpmock

  • Specifically designed for mocking HTTP requests, making it more straightforward for HTTP-related testing
  • Lightweight and easy to set up, with a simple API for stubbing HTTP responses
  • Supports both global and local HTTP mocking, offering flexibility in test design

Cons of httpmock

  • Limited to HTTP mocking, whereas mock is a more general-purpose mocking framework
  • Less extensive feature set compared to mock, which offers more advanced mocking capabilities
  • May require additional setup for complex scenarios that go beyond simple HTTP request/response mocking

Code Comparison

httpmock:

httpmock.Activate()
defer httpmock.DeactivateAndReset()

httpmock.RegisterResponder("GET", "https://api.example.com/users",
    httpmock.NewStringResponder(200, `[{"id": 1, "name": "John"}]`))

mock:

ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockService := mock_service.NewMockUserService(ctrl)
mockService.EXPECT().GetUsers().Return([]User{{ID: 1, Name: "John"}}, nil)

The httpmock example shows how to stub an HTTP response, while the mock example demonstrates creating a mock service with expected method calls. httpmock is more focused on HTTP interactions, while mock provides a broader mocking framework for various types of dependencies.

2,079

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽

Pros of gock

  • Simpler API for HTTP mocking, requiring less setup code
  • Built-in support for JSON matching and custom matchers
  • Easier to use for API testing scenarios

Cons of gock

  • Limited to HTTP mocking, less versatile for general-purpose mocking
  • Lacks code generation capabilities for creating mock interfaces

Code Comparison

gock:

defer gock.Off()
gock.New("https://api.example.com").
    Get("/users").
    Reply(200).
    JSON(map[string]string{"name": "John"})

mock:

ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockObj := NewMockInterface(ctrl)
mockObj.EXPECT().Method(gomock.Any()).Return("result")

Key Differences

  • gock focuses on HTTP mocking, while mock is a general-purpose mocking framework
  • gock provides a more fluent API for setting up HTTP mocks
  • mock generates mock implementations of interfaces, allowing for broader mocking capabilities
  • gock is better suited for API testing, while mock is more versatile for unit testing various components

Use Cases

  • Choose gock for API and integration testing involving HTTP requests
  • Opt for mock when you need to create mock implementations of interfaces or for more complex mocking scenarios in unit tests
3,339

Monkey patching in Go

Pros of monkey

  • Allows mocking of static functions and methods, which is not possible with mock
  • Provides runtime patching, enabling dynamic behavior modification during tests
  • Simpler setup and less boilerplate code compared to mock

Cons of monkey

  • Can be unsafe and lead to unexpected behavior if not used carefully
  • Limited to Go's supported platforms and architectures
  • May not work well with optimized or inlined code

Code Comparison

mock:

ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockObj := NewMockInterface(ctrl)
mockObj.EXPECT().SomeMethod(gomock.Any()).Return(42)

monkey:

patch := monkey.Patch(time.Now, func() time.Time {
    return time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC)
})
defer patch.Unpatch()

Summary

While mock focuses on interface-based mocking and follows a more traditional approach, monkey offers powerful runtime patching capabilities. mock is generally safer and more widely applicable, but monkey provides unique features for specific testing scenarios. The choice between them depends on the specific requirements of your testing environment and the level of control you need over function behavior during tests.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

gomock

Update, June 2023: This repo and tool are no longer maintained. Please see go.uber.org/mock for a maintained fork instead.

Build Status Go Reference

gomock is a mocking framework for the Go programming language. It integrates well with Go's built-in testing package, but can be used in other contexts too.

Installation

Once you have installed Go, install the mockgen tool.

Note: If you have not done so already be sure to add $GOPATH/bin to your PATH.

To get the latest released version use:

Go version < 1.16

GO111MODULE=on go get github.com/golang/mock/mockgen@v1.6.0

Go 1.16+

go install github.com/golang/mock/mockgen@v1.6.0

If you use mockgen in your CI pipeline, it may be more appropriate to fixate on a specific mockgen version. You should try to keep the library in sync with the version of mockgen used to generate your mocks.

Running mockgen

mockgen has two modes of operation: source and reflect.

Source mode

Source mode generates mock interfaces from a source file. It is enabled by using the -source flag. Other flags that may be useful in this mode are -imports and -aux_files.

Example:

mockgen -source=foo.go [other options]

Reflect mode

Reflect mode generates mock interfaces by building a program that uses reflection to understand interfaces. It is enabled by passing two non-flag arguments: an import path, and a comma-separated list of symbols.

You can use "." to refer to the current path's package.

Example:

mockgen database/sql/driver Conn,Driver

# Convenient for `go:generate`.
mockgen . Conn,Driver

Flags

The mockgen command is used to generate source code for a mock class given a Go source file containing interfaces to be mocked. It supports the following flags:

  • -source: A file containing interfaces to be mocked.

  • -destination: A file to which to write the resulting source code. If you don't set this, the code is printed to standard output.

  • -package: The package to use for the resulting mock class source code. If you don't set this, the package name is mock_ concatenated with the package of the input file.

  • -imports: A list of explicit imports that should be used in the resulting source code, specified as a comma-separated list of elements of the form foo=bar/baz, where bar/baz is the package being imported and foo is the identifier to use for the package in the generated source code.

  • -aux_files: A list of additional files that should be consulted to resolve e.g. embedded interfaces defined in a different file. This is specified as a comma-separated list of elements of the form foo=bar/baz.go, where bar/baz.go is the source file and foo is the package name of that file used by the -source file.

  • -build_flags: (reflect mode only) Flags passed verbatim to go build.

  • -mock_names: A list of custom names for generated mocks. This is specified as a comma-separated list of elements of the form Repository=MockSensorRepository,Endpoint=MockSensorEndpoint, where Repository is the interface name and MockSensorRepository is the desired mock name (mock factory method and mock recorder will be named after the mock). If one of the interfaces has no custom name specified, then default naming convention will be used.

  • -self_package: The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.

  • -copyright_file: Copyright file used to add copyright header to the resulting source code.

  • -debug_parser: Print out parser results only.

  • -exec_only: (reflect mode) If set, execute this reflection program.

  • -prog_only: (reflect mode) Only generate the reflection program; write it to stdout and exit.

  • -write_package_comment: Writes package documentation comment (godoc) if true. (default true)

For an example of the use of mockgen, see the sample/ directory. In simple cases, you will need only the -source flag.

Building Mocks

type Foo interface {
  Bar(x int) int
}

func SUT(f Foo) {
 // ...
}

func TestFoo(t *testing.T) {
  ctrl := gomock.NewController(t)

  // Assert that Bar() is invoked.
  defer ctrl.Finish()

  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)
}

If you are using a Go version of 1.14+, a mockgen version of 1.5.0+, and are passing a *testing.T into gomock.NewController(t) you no longer need to call ctrl.Finish() explicitly. It will be called for you automatically from a self registered Cleanup function.

Building Stubs

type Foo interface {
  Bar(x int) int
}

func SUT(f Foo) {
 // ...
}

func TestFoo(t *testing.T) {
  ctrl := gomock.NewController(t)
  defer ctrl.Finish()

  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)
}

Modifying Failure Messages

When a matcher reports a failure, it prints the received (Got) vs the expected (Want) value.

Got: [3]
Want: is equal to 2
Expected call at user_test.go:33 doesn't match the argument at index 1.
Got: [0 1 1 2 3]
Want: is equal to 1

Modifying Want

The Want value comes from the matcher's String() method. If the matcher's default output doesn't meet your needs, then it can be modified as follows:

gomock.WantFormatter(
  gomock.StringerFunc(func() string { return "is equal to fifteen" }),
  gomock.Eq(15),
)

This modifies the gomock.Eq(15) matcher's output for Want: from is equal to 15 to is equal to fifteen.

Modifying Got

The Got value comes from the object's String() method if it is available. In some cases the output of an object is difficult to read (e.g., []byte) and it would be helpful for the test to print it differently. The following modifies how the Got value is formatted:

gomock.GotFormatterAdapter(
  gomock.GotFormatterFunc(func(i interface{}) string {
    // Leading 0s
    return fmt.Sprintf("%02d", i)
  }),
  gomock.Eq(15),
)

If the received value is 3, then it will be printed as 03.

Debugging Errors

reflect vendoring error

cannot find package "."
... github.com/golang/mock/mockgen/model

If you come across this error while using reflect mode and vendoring dependencies there are three workarounds you can choose from:

  1. Use source mode.
  2. Include an empty import import _ "github.com/golang/mock/mockgen/model".
  3. Add --build_flags=--mod=mod to your mockgen command.

This error is due to changes in default behavior of the go command in more recent versions. More details can be found in #494.