From d9ac6780152ff37d80ed7a60a496b5bd4cd8a53c Mon Sep 17 00:00:00 2001 From: Stephen Wan Date: Fri, 12 Jun 2020 14:28:05 -0700 Subject: [PATCH] gomock/controller: use skip additional frame (#443) In 832173191abead7f0878d8bb24f32f1a5fdf6d79, the callerInfo call gets nested within an additional function call, but the frame skip isn't updated. When used with mockgen, this causes the location frame to unhelpfully point to the generated mock instead of the callsite in the user's test. Add an explanation for future readers, explaining callerInfo and when it should be updated. --- gomock/call.go | 3 +++ gomock/controller.go | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gomock/call.go b/gomock/call.go index 7345f654..49d35846 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -63,6 +63,9 @@ func newCall(t TestHelper, receiver interface{}, method string, methodType refle } } + // callerInfo's skip should be updated if the number of calls between the user's test + // and this line changes, i.e. this code is wrapped in another anonymous function. + // 0 is us, 1 is RecordCallWithMethodType(), 2 is the generated recorder, and 3 is the user's test. origin := callerInfo(3) actions := []func([]interface{}) []interface{}{func([]interface{}) []interface{} { // Synthesize the zero value for each of the return args' types. diff --git a/gomock/controller.go b/gomock/controller.go index 0a8366b9..ee175cdd 100644 --- a/gomock/controller.go +++ b/gomock/controller.go @@ -224,7 +224,10 @@ func (ctrl *Controller) Call(receiver interface{}, method string, args ...interf expected, err := ctrl.expectedCalls.FindMatch(receiver, method, args) if err != nil { - origin := callerInfo(2) + // callerInfo's skip should be updated if the number of calls between the user's test + // and this line changes, i.e. this code is wrapped in another anonymous function. + // 0 is us, 1 is controller.Call(), 2 is the generated mock, and 3 is the user's test. + origin := callerInfo(3) ctrl.T.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err) } @@ -291,6 +294,8 @@ func (ctrl *Controller) Finish() { } } +// callerInfo returns the file:line of the call site. skip is the number +// of stack frames to skip when reporting. 0 is callerInfo's call site. func callerInfo(skip int) string { if _, file, line, ok := runtime.Caller(skip + 1); ok { return fmt.Sprintf("%s:%d", file, line)