mock

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2026 License: MIT Imports: 9 Imported by: 0

README

mock

A lightweight Go mock generator that creates struct-based mocks from interfaces using //go:generate directives.

How it works

  1. Annotate any interface with //go:generate go tool mock
  2. Run go generate ./...
  3. A gen_<filename>_mock.go file is created alongside the source file

For each annotated interface, mock generates a struct where every method is backed by a function field. This makes mocks trivial to set up inline in tests — no reflection, no DSL, just plain Go.

Installation

As a Go tool (recommended) - tracked in your module and versioned with it:

go get -tool codeberg.org/datek/mock/cmd/mock@latest

This adds a tool directive to your go.mod and makes the binary available via go tool mock.

As a standalone binary:

go install codeberg.org/datek/mock/cmd/mock@latest

Usage

1. Annotate your interfaces
// service.go
package mypackage

//go:generate go tool mock
type UserStore interface {
    GetUser(id int) (*User, error)
    SaveUser(u *User) error
    DeleteUser(id int)
}

Only interfaces immediately preceded by //go:generate go tool mock are processed. Interfaces without the directive are left untouched.

2. Generate the mocks
go generate ./...

This produces gen_service_mock.go in the same package:

// Code generated by mock; DO NOT EDIT.
package mypackage

type UserStoreMock struct {
    GetUserMock    func(id int) (*User, error)
    SaveUserMock   func(u *User) error
    DeleteUserMock func(id int)
}

func (mock *UserStoreMock) GetUser(id int) (*User, error) {
    return mock.GetUserMock(id)
}

func (mock *UserStoreMock) SaveUser(u *User) error {
    return mock.SaveUserMock(u)
}

func (mock *UserStoreMock) DeleteUser(id int) {
    mock.DeleteUserMock(id)
}

var _ UserStore = &UserStoreMock{}

The var _ UserStore = &UserStoreMock{} line provides a compile-time guarantee that the mock fully satisfies the interface.

3. Use the mock in tests
// service_test.go
package mypackage_test

import (
    "errors"
    "testing"
)

func TestGetUserReturnsError(t *testing.T) {
    store := &UserStoreMock{
        GetUserMock: func(id int) (*User, error) {
            return nil, errors.New("not found")
        },
    }

    svc := NewUserService(store)
    _, err := svc.GetUser(42)
    if err == nil {
        t.Fatal("expected error, got nil")
    }
}

You only need to set the function fields relevant to your test. Unset fields will panic if called, catching unexpected interactions early.

Example with multiple interfaces

// repo.go
package orders

//go:generate go tool mock
type OrderRepo interface {
    Find(id string) (*Order, error)
    Create(o *Order) error
}

//go:generate go tool mock
type PaymentGateway interface {
    Charge(amount int, token string) (string, error)
}

Running go generate produces mocks for both OrderRepo and PaymentGateway in a single gen_repo_mock.go file. Interfaces in the same file without the directive (e.g. a third AuditLog interface) are skipped.

Using the library directly

The Generate function is exported and can be used programmatically:

import "codeberg.org/datek/mock"

src, _ := os.ReadFile("service.go")
output, err := mock.Generate(src, "service.go")
if err != nil {
    log.Fatal(err)
}
os.WriteFile("gen_service_mock.go", output, 0644)

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Comments = []string{
	"//go:generate mock",
	"//go:generate go tool mock",
}

Functions

func Generate

func Generate(src []byte, filename string) ([]byte, error)

Types

This section is empty.

Directories

Path Synopsis
cmd
mock command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL