#622·mock

Type-safe return values

Author: trim21Created Feb 14, 2022Updated Mar 1, 2023
Labelsstatus: needs more infotype: feature request

Requested feature

This issue proposal generating a typed .Return( for *gomock.Call.

it's a re-open for closed issue #427 .

Why the feature is needed

currently .Return( has a sigurate of func (rets ...interface{}) can accept any return value in compile time.

But wrong return values' type result in always failing at runtime, which can be avoided at compile time.

Proposed solution

User Code

go
type Auth interface {
	// GetByToken return an authorized user by a valid access token.
	GetByToken(ctx context.Context, token string) (model.User, error)
}

Generated mocks

go
// Code generated by MockGen. DO NOT EDIT.

type MockAuthMockRecorder struct {
	...
}

// GetByToken indicates an expected call of GetByToken.
func (mr *MockAuthMockRecorder) GetByToken(ctx, token interface{}) *TypedCall {
	mr.mock.ctrl.T.Helper()
	return &TypedCall{mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByToken",
		reflect.TypeOf((*MockAuth)(nil).GetByToken), ctx, token)}
}


type TypedCall struct {
	*gomock.Call
}

func (t *TypedCall) Return(typedReturn1 model.User, typedReturn2 error) *gomock.Call {
	return t.Call.Return(typedReturn1, typedReturn2)
}

User Test Code

go
func TestTypeSafeReturn(t *testing.T) {
	m := NewMockAuth(gomock.NewController(t))
	m.GetByToken(gomock.Any(), gomock.Any()).Return() <== Now we get compile time error

	// These should works fine at compile time and runtime.
	m.GetByToken(gomock.Any(), gomock.Any()).Return(model.User{}, nil)
	m.GetByToken(gomock.Any(), gomock.Any()).Return(model.User{}, errors.New("Not Found")) 
}