Skip to content

toniphan21/go-mock-gen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-mock-gen codecov Go Report Card Go Reference

go-mock-gen is a tool to generate a type-safe, minimal, zero-dependency and idiomatic mock for testing with a strong focus on Developer Experience. There are no any, no magic matchers. The API is designed so you can't do anything wrong - and when you do, it tells you exactly why, where, and how to fix it.

Quick Demo

Quick Usage

You can run the command to generate directly via go run.

go run nhatp.com/go/mock-gen/cmd/go-mock-gen -i Interface -o mock_interface_test.go

To install the go-mock-gen command, run

go install nhatp.com/go/mock-gen/cmd/go-mock-gen

options

> go-mock-gen --help
Usage: go-mock-gen [--interface NAMES] [--struct STRUCT] [--package PKG_NAME] [--output PATH] [--dry-run] [--example] [--omit-expect] [--no-color] <command> [<args>]

Options:
  --interface NAMES, -i NAMES
                         comma-separated list of interfaces to mock. Supports:
                           - local    : Repository
                           - qualified: io.Reader
                           - full path: github.com/user/pkg.Interface
  --struct STRUCT, -s STRUCT
                         struct name for the generated mock; only valid when mocking a single interface;
                         defaults to the unexported interface name (e.g. Repository -> repository)
  --package PKG_NAME, -p PKG_NAME
                         package name for the generated code. Defaults to the source package name of the interface
  --output PATH, -o PATH
                         output file for the generated code [default: mockgen_test.go]
  --dry-run, -d          preview changes without writing to disk [default: false]
  --example              emit test examples [default: false]
  --omit-expect          omit EXPECT mock generation [default: false]
  --no-color             disable colors [default: false]
  --help, -h             display this help and exit

Commands:
  version                print version information and exit

Examples:
  # Generate a mock for a local interface:
  go-mock-gen -i Repository

  # Generate a mock for a single interface with example tests:
  go-mock-gen -i Repository --example

  # Generate a mock from standard library or external packages:
  go-mock-gen -i io.Reader,net/http.RoundTripper

  # Generate mocks for multiple local interfaces:
  go-mock-gen -i Repository,UserService

  # Generate a mock with a custom struct name:
  go-mock-gen -i Repository -s repoMock

  # Generate with a custom package and output file:
  go-mock-gen -i Repository -s Repository -p mock -o mock/mockgen_test.go

API

There are two API categories:

  • The .EXPECT() way is for convenience.
  • The .STUB() way is for fine-grained control.

On the same method, you cannot mix between them, otherwise the test will fail immediately.

.EXPECT()

There are only 10 ways to set an expectation - no Once(), no Twice(), no Times(). If you want to expect 2 calls, just use EXPECT twice.

after .EXPECT().Method(t) Arguments Return Usage
<empty> - zero expect the call, ignore args
.Return(…) - ignore args
.With(…) all, value zero match all args by value
.With(…).Return(…) all, value match all args by value
.With[Arg](…) partial, value zero match argument(s) by value
.With[Arg](…).Return(…) partial, value match argument(s) by value
.Match(func(…) bool) all, callback zero match all args by callback
.Match(func(…) bool).Return(…) all, callback match all args by callback
.Match[Arg](func(…) bool) partial, callback zero match argument(s) by callback
.Match[Arg](func(…) bool).Return(…) partial, callback match argument(s) by callback

If you use it in a wrong way the IDE will show you the error. In case it is not a syntax error the test will fail and show you exactly why.

Quick example:

package test

import "testing"

func Test_Quick_Expect_Example(t *testing.T) {
	repo := testRepository()

	t.Run("expect one call - ignore args - return zero", func(t *testing.T) {
		repo.EXPECT().GetUsers(t)
		// ...
		repo.GetUsers(...)
	})

	t.Run("expect two calls - first call match arg - second call stub return", func(t *testing.T) {
		repo.EXPECT().GetUsers(t).With(...)
		repo.EXPECT().GetUsers(t).Return(...)
		// ...
		repo.GetUsers(...)
		out := repo.GetUsers(...)
	})
}

.STUB()

The STUB API is even simpler than EXPECT. You need to provide a function with the same signature as the implementation, and it returns a spy for you to assert yourself:

package test

import (
	"fmt"
	"testing"
)

func Test_STUB(t *testing.T) {
	repo := testRepository()

	spy := repo.STUB().GetUsers(func(input string) []string {
		// inspect calls yourself
		if input != "awesome" {
			t.Fatal("hey, be awesome")
		}
		return nil
	})

	// ...test code...

	// inspect calls yourself
	if len(spy.Calls) != 1 {
		t.Fatal("why didn't you call me?")
	}

	if spy.Calls[0].Arguments.Input == "awesome" {
		fmt.Println("good!")
	}
}

Screenshots

Syntax error when mix partial and full match You cannot mix between matching all arguments or partial argument(s), enforced at the syntax level

Syntax error when mix With and Match You cannot mix between argument via value or a callback, enforced at the syntax level

mixed EXPECT() and STUB() You cannot use .EXPECT() and .STUB() on the same method

pass nil When nil is passed where it is not expected, go-mock-gen tells you why and where

failed call not expected Error message when a call is not expected with full history

failed expect but not called Error message when expected but not called with full history

failed match value failed Error message when expected argument by value fails

failed match value failed Error message when match argument callback returns false

Contributing & License

PRs are welcome! See the CONTRIBUTING. Distributed under the Apache License 2.0.

If you like the project, feel free to buy me a coffee. Thank you!

About

A type-safe, minimal, zero-dependency and idiomatic mock generator with a strong focus on the Developer Experience

Topics

Resources

License

Contributing

Stars

Watchers

Forks