Skip to content

gomock.Captor[T any] for argument inspection #300

@kliukovkin

Description

@kliukovkin

This is a proposal to add gomock.Captor[T any], a generic, type-asserting matcher that records argument values passed to a mocked method so tests can inspect them after the run.

Currently the only way to inspect arguments in gomock is Do(func(arg T){ captured = arg }). This works but has two real problems. First, it couples the test to the full method signature: adding a parameter to the interface forces every existing Do callback to be updated. Second, with -typed mocks the callback already has to match the typed signature, which makes capture-and-otherwise-default behavior awkward to express. A first-class captor sidesteps both. The test only declares what type it cares about.

API sketch:

captor := gomock.NewCaptor[Order]()
mock.EXPECT().Process(captor).Return(nil)
// run code under test
got := captor.Value()    // last captured Order; panics if none
all := captor.Values()   // []Order, all calls

Captor[T] implements Matcher. Matches type-asserts to T; values of other types do not match and are not recorded, so it composes with AnyOf and similar matchers. Captures are guarded by a mutex for goroutine-driven mock calls. TryValue is the safe form of Value for tests that want to assert capture count separately.

Prior art: golang/mock#262 with PR golang/mock#263 attempted this in the predecessor repo. It was abandoned at archive time, never declined on merits. The language has generics now, which wasn't true when #263 was open, so the API is clean.

Self-contained type, no external deps, matches the criterion from the #154 thread.

Happy to drive the implementation if there is interest.

Tagging @sywhang @r-hang @abhinav.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions