Skip to content

Commit 921da25

Browse files
Dinesh Kumarernesto-jimenez
authored andcommitted
Displaying mismatch information of arguments diff while panic for closest function call. closes #556
1 parent 6efb0c4 commit 921da25

File tree

2 files changed

+70
-12
lines changed

2 files changed

+70
-12
lines changed

mock/mock.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,27 +249,25 @@ func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *
249249
return -1, nil
250250
}
251251

252-
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
253-
diffCount := 0
252+
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (*Call, string) {
253+
var diffCount int
254254
var closestCall *Call
255+
var err string
255256

256257
for _, call := range m.expectedCalls() {
257258
if call.Method == method {
258259

259-
_, tempDiffCount := call.Arguments.Diff(arguments)
260+
errInfo, tempDiffCount := call.Arguments.Diff(arguments)
260261
if tempDiffCount < diffCount || diffCount == 0 {
261262
diffCount = tempDiffCount
262263
closestCall = call
264+
err = errInfo
263265
}
264266

265267
}
266268
}
267269

268-
if closestCall == nil {
269-
return false, nil
270-
}
271-
272-
return true, closestCall
270+
return closestCall, err
273271
}
274272

275273
func callString(method string, arguments Arguments, includeArgumentValues bool) string {
@@ -316,6 +314,7 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
316314
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
317315
func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
318316
m.mutex.Lock()
317+
//TODO: could combine expected and closes in single loop
319318
found, call := m.findExpectedCall(methodName, arguments...)
320319

321320
if found < 0 {
@@ -326,11 +325,16 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
326325
// b) the arguments are not what was expected, or
327326
// c) the developer has forgotten to add an accompanying On...Return pair.
328327

329-
closestFound, closestCall := m.findClosestCall(methodName, arguments...)
328+
closestCall, mismatch := m.findClosestCall(methodName, arguments...)
330329
m.mutex.Unlock()
331330

332-
if closestFound {
333-
panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(closestCall.Arguments, arguments)))
331+
if closestCall != nil {
332+
panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s",
333+
callString(methodName, arguments, true),
334+
callString(methodName, closestCall.Arguments, true),
335+
diffArguments(closestCall.Arguments, arguments),
336+
strings.TrimSpace(mismatch)),
337+
)
334338
} else {
335339
panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()))
336340
}
@@ -627,6 +631,7 @@ func (args Arguments) Is(objects ...interface{}) bool {
627631
//
628632
// Returns the diff string and number of differences found.
629633
func (args Arguments) Diff(objects []interface{}) (string, int) {
634+
//TODO: could return string as error and nil for No difference
630635

631636
var output = "\n"
632637
var differences int

mock/mock_test.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import (
88
"testing"
99
"time"
1010

11+
"runtime"
12+
1113
"github.com/stretchr/testify/assert"
1214
"github.com/stretchr/testify/require"
13-
"runtime"
1415
)
1516

1617
/*
@@ -1384,6 +1385,58 @@ func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
13841385
}
13851386
}
13861387

1388+
func TestArgumentMatcherToPrintMismatch(t *testing.T) {
1389+
defer func() {
1390+
if r := recover(); r != nil {
1391+
matchingExp := regexp.MustCompile(
1392+
`\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool`)
1393+
assert.Regexp(t, matchingExp, r)
1394+
}
1395+
}()
1396+
1397+
m := new(timer)
1398+
m.On("GetTime", MatchedBy(func(i int) bool { return false })).Return("SomeTime").Once()
1399+
1400+
res := m.GetTime(1)
1401+
require.Equal(t, "SomeTime", res)
1402+
m.AssertExpectations(t)
1403+
}
1404+
1405+
func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) {
1406+
defer func() {
1407+
if r := recover(); r != nil {
1408+
matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod(int,int,int)`, `0: 1\s+1: 1\s+2: 2`, `0: 1\s+1: 1\s+2: 1`, `0: PASS: %!s\(int=1\) == %!s\(int=1\)\s+1: PASS: %!s\(int=1\) == %!s\(int=1\)\s+2: FAIL: %!s\(int=2\) != %!s\(int=1\)`))
1409+
assert.Regexp(t, matchingExp, r)
1410+
}
1411+
}()
1412+
1413+
m := new(TestExampleImplementation)
1414+
m.On("TheExampleMethod", 1, 1, 1).Return(1, nil).Once()
1415+
m.On("TheExampleMethod", 2, 2, 2).Return(2, nil).Once()
1416+
1417+
m.TheExampleMethod(1, 1, 2)
1418+
}
1419+
1420+
func TestClosestCallMismatchedArgumentValueInformation(t *testing.T) {
1421+
defer func() {
1422+
if r := recover(); r != nil {
1423+
matchingExp := regexp.MustCompile(unexpectedCallRegex(`GetTime(int)`, "0: 1", "0: 999", `0: FAIL: %!s\(int=1\) != %!s\(int=999\)`))
1424+
assert.Regexp(t, matchingExp, r)
1425+
}
1426+
}()
1427+
1428+
m := new(timer)
1429+
m.On("GetTime", 999).Return("SomeTime").Once()
1430+
1431+
_ = m.GetTime(1)
1432+
}
1433+
1434+
func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
1435+
rMethod := regexp.QuoteMeta(method)
1436+
return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+Diff: %s`,
1437+
rMethod, calledArg, rMethod, expectedArg, diff)
1438+
}
1439+
13871440
func ConcurrencyTestMethod(m *Mock) {
13881441
m.Called()
13891442
}

0 commit comments

Comments
 (0)