Skip to content

Proposal: mocking function types #218

Open
@PeterEFinch

Description

@PeterEFinch

The idea: Adding the functionality to mock function types.

The motivation: Functions are first class objects that are passed into functions/methods and stored in structs. To test that we have the desired behaviour where they are being used it would be useful to be able to mock them in a similar fashion to interfaces.

What I am asking: Would you consider adding support for such functionality? See below for an example setup and expected result. N.B. I thought it useful to ask if you would consider it before I attempt to implement a solution.


The expectation would be that running go generate on

//go:generate moq -out mocks.go . Solver

// Solver represent a function that solves a problem that
// takes a long time.
type Solver func(ctx context.Context, in [][]int) ([]int, error)

yields something (along with suitable documentation) similar to

import (
	"context"
	"sync"
)

var _ Solver = (*SolverMock)(nil).Call

type SolverMock struct {
	Func func(ctx context.Context, in [][]int) ([]int, error)

	calls []struct {
		Ctx context.Context
		In  [][]int
	}

	mu sync.RWMutex
}

func (e *SolverMock) Call(ctx context.Context, in [][]int) ([]int, error) {
	if e.Func == nil {
		panic("SolverMock.Func: method is nil but Call was just called")
	}

	callInfo := struct {
		Ctx context.Context
		In  [][]int
	}{
		Ctx: ctx,
		In:  in,
	}

	e.mu.Lock()
	e.calls = append(e.calls, callInfo)
	e.mu.Unlock()

	return e.Func(ctx, in)
}

func (e *SolverMock) Calls() []struct {
	Ctx context.Context
	In  [][]int
} {
	var calls []struct {
		Ctx context.Context
		In  [][]int
	}
	e.mu.RLock()
	calls = e.calls
	e.mu.RUnlock()
	return calls
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions