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

Commit f9b4ad1

Browse files
authored
Fix #71 Do + DoAndReturn signature change error msg (#395)
Update the error handling for Call.Do and Call.DoAndReturn in the case where the argument passed does not match expectations. * panic if the argument is not a function * panic if the number of input arguments do not match those expected by Call * panic if the types of the input arguments do not match those expected by Call Call.DoAndReturn has additional validations on the return signature * panic if the number of return arguments do not match those expected by Call * panic if the types of return arguments do not match those expected by Call
1 parent b48cb66 commit f9b4ad1

File tree

4 files changed

+1109
-3
lines changed

4 files changed

+1109
-3
lines changed

gomock/call.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"reflect"
2020
"strconv"
2121
"strings"
22+
23+
"github.com/golang/mock/gomock/internal/validate"
2224
)
2325

2426
// Call represents an expected call to a mock.
@@ -105,10 +107,24 @@ func (c *Call) MaxTimes(n int) *Call {
105107
// DoAndReturn declares the action to run when the call is matched.
106108
// The return values from this function are returned by the mocked function.
107109
// It takes an interface{} argument to support n-arity functions.
110+
// If the method signature of f is not compatible with the mocked function a
111+
// panic will be triggered. Both the arguments and return values of f are
112+
// validated.
108113
func (c *Call) DoAndReturn(f interface{}) *Call {
109-
// TODO: Check arity and types here, rather than dying badly elsewhere.
110114
v := reflect.ValueOf(f)
111115

116+
switch v.Kind() {
117+
case reflect.Func:
118+
mt := c.methodType
119+
120+
ft := v.Type()
121+
if err := validate.InputAndOutputSig(ft, mt); err != nil {
122+
panic(fmt.Sprintf("DoAndReturn: %s", err))
123+
}
124+
default:
125+
panic("DoAndReturn: argument must be a function")
126+
}
127+
112128
c.addAction(func(args []interface{}) []interface{} {
113129
vargs := make([]reflect.Value, len(args))
114130
ft := v.Type()
@@ -134,10 +150,24 @@ func (c *Call) DoAndReturn(f interface{}) *Call {
134150
// return values are ignored to retain backward compatibility. To use the
135151
// return values call DoAndReturn.
136152
// It takes an interface{} argument to support n-arity functions.
153+
// If the method signature of f is not compatible with the mocked function a
154+
// panic will be triggered. Only the arguments of f are validated; not the return
155+
// values.
137156
func (c *Call) Do(f interface{}) *Call {
138-
// TODO: Check arity and types here, rather than dying badly elsewhere.
139157
v := reflect.ValueOf(f)
140158

159+
switch v.Kind() {
160+
case reflect.Func:
161+
mt := c.methodType
162+
163+
ft := v.Type()
164+
if err := validate.InputSig(ft, mt); err != nil {
165+
panic(fmt.Sprintf("Do: %s", err))
166+
}
167+
default:
168+
panic("Do: argument must be a function")
169+
}
170+
141171
c.addAction(func(args []interface{}) []interface{} {
142172
vargs := make([]reflect.Value, len(args))
143173
ft := v.Type()

0 commit comments

Comments
 (0)