Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 96d9cb5

Browse files
authored
Don't error out for variadic functions in Do/DoReturn (#601)
Fixes: #600
1 parent bdab070 commit 96d9cb5

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

gomock/call.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,25 @@ func (c *Call) MaxTimes(n int) *Call {
108108
// DoAndReturn declares the action to run when the call is matched.
109109
// The return values from this function are returned by the mocked function.
110110
// It takes an interface{} argument to support n-arity functions.
111-
// The anonymous function must have the same number of input and output arguments as the mocked method.
111+
// The anonymous function must match the function signature mocked method.
112112
func (c *Call) DoAndReturn(f interface{}) *Call {
113113
// TODO: Check arity and types here, rather than dying badly elsewhere.
114114
v := reflect.ValueOf(f)
115115

116116
c.addAction(func(args []interface{}) []interface{} {
117117
c.t.Helper()
118-
vArgs := make([]reflect.Value, len(args))
119118
ft := v.Type()
120119
if c.methodType.NumIn() != ft.NumIn() {
121-
c.t.Fatalf("wrong number of arguments in DoAndReturn func for %T.%v: got %d, want %d [%s]",
122-
c.receiver, c.method, ft.NumIn(), c.methodType.NumIn(), c.origin)
120+
if ft.IsVariadic() {
121+
c.t.Fatalf("wrong number of arguments in DoAndReturn func for %T.%v The function signature must match the mocked method, a variadic function cannot be used.",
122+
c.receiver, c.method)
123+
} else {
124+
c.t.Fatalf("wrong number of arguments in DoAndReturn func for %T.%v: got %d, want %d [%s]",
125+
c.receiver, c.method, ft.NumIn(), c.methodType.NumIn(), c.origin)
126+
}
123127
return nil
124128
}
129+
vArgs := make([]reflect.Value, len(args))
125130
for i := 0; i < len(args); i++ {
126131
if args[i] != nil {
127132
vArgs[i] = reflect.ValueOf(args[i])
@@ -144,20 +149,25 @@ func (c *Call) DoAndReturn(f interface{}) *Call {
144149
// return values are ignored to retain backward compatibility. To use the
145150
// return values call DoAndReturn.
146151
// It takes an interface{} argument to support n-arity functions.
147-
// The anonymous function must have the same number of input arguments as the mocked method.
152+
// The anonymous function must match the function signature mocked method.
148153
func (c *Call) Do(f interface{}) *Call {
149154
// TODO: Check arity and types here, rather than dying badly elsewhere.
150155
v := reflect.ValueOf(f)
151156

152157
c.addAction(func(args []interface{}) []interface{} {
153158
c.t.Helper()
154-
if c.methodType.NumIn() != v.Type().NumIn() {
155-
c.t.Fatalf("wrong number of arguments in Do func for %T.%v: got %d, want %d [%s]",
156-
c.receiver, c.method, v.Type().NumIn(), c.methodType.NumIn(), c.origin)
159+
ft := v.Type()
160+
if c.methodType.NumIn() != ft.NumIn() {
161+
if ft.IsVariadic() {
162+
c.t.Fatalf("wrong number of arguments in Do func for %T.%v The function signature must match the mocked method, a variadic function cannot be used.",
163+
c.receiver, c.method)
164+
} else {
165+
c.t.Fatalf("wrong number of arguments in Do func for %T.%v: got %d, want %d [%s]",
166+
c.receiver, c.method, ft.NumIn(), c.methodType.NumIn(), c.origin)
167+
}
157168
return nil
158169
}
159170
vArgs := make([]reflect.Value, len(args))
160-
ft := v.Type()
161171
for i := 0; i < len(args); i++ {
162172
if args[i] != nil {
163173
vArgs[i] = reflect.ValueOf(args[i])

gomock/call_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,13 @@ func TestCall_Do_NumArgValidation(t *testing.T) {
510510
args: []interface{}{"just", "right"},
511511
wantErr: false,
512512
},
513+
{
514+
name: "variadic",
515+
methodType: reflect.TypeOf(func(one, two string) {}),
516+
doFn: func(args ...interface{}) {},
517+
args: []interface{}{"just", "right"},
518+
wantErr: true,
519+
},
513520
}
514521
for _, tt := range tests {
515522
t.Run(tt.name, func(t *testing.T) {
@@ -559,6 +566,13 @@ func TestCall_DoAndReturn_NumArgValidation(t *testing.T) {
559566
args: []interface{}{"just", "right"},
560567
wantErr: false,
561568
},
569+
{
570+
name: "variadic",
571+
methodType: reflect.TypeOf(func(one, two string) {}),
572+
doFn: func(args ...interface{}) string { return "" },
573+
args: []interface{}{"just", "right"},
574+
wantErr: true,
575+
},
562576
}
563577
for _, tt := range tests {
564578
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)