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

Commit

Permalink
Fix #71 Do + DoAndReturn signature change error msg
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cvgw committed Feb 28, 2020
1 parent b48cb66 commit e3d5d28
Show file tree
Hide file tree
Showing 4 changed files with 1,109 additions and 3 deletions.
34 changes: 32 additions & 2 deletions gomock/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"reflect"
"strconv"
"strings"

"github.com/golang/mock/gomock/internal/validate"
)

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

switch v.Kind() {
case reflect.Func:
mt := c.methodType

ft := v.Type()
if err := validate.InputAndOutputSig(ft, mt); err != nil {
panic(fmt.Sprintf("DoAndReturn: %s", err))
}
default:
panic("DoAndReturn: argument must be a function")
}

c.addAction(func(args []interface{}) []interface{} {
vargs := make([]reflect.Value, len(args))
ft := v.Type()
Expand All @@ -134,10 +150,24 @@ func (c *Call) DoAndReturn(f interface{}) *Call {
// return values are ignored to retain backward compatibility. To use the
// return values call DoAndReturn.
// It takes an interface{} argument to support n-arity functions.
// If the method signature of f is not compatible with the mocked function a
// panic will be triggered. Only the arguments of f are validated; not the return
// values.
func (c *Call) Do(f interface{}) *Call {
// TODO: Check arity and types here, rather than dying badly elsewhere.
v := reflect.ValueOf(f)

switch v.Kind() {
case reflect.Func:
mt := c.methodType

ft := v.Type()
if err := validate.InputSig(ft, mt); err != nil {
panic(fmt.Sprintf("Do: %s", err))
}
default:
panic("Do: argument must be a function")
}

c.addAction(func(args []interface{}) []interface{} {
vargs := make([]reflect.Value, len(args))
ft := v.Type()
Expand Down
Loading

0 comments on commit e3d5d28

Please sign in to comment.