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.
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 existingDocallback to be updated. Second, with-typedmocks 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[T]implementsMatcher.Matchestype-asserts toT; values of other types do not match and are not recorded, so it composes withAnyOfand similar matchers. Captures are guarded by a mutex for goroutine-driven mock calls.TryValueis the safe form ofValuefor 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.