mirror of https://github.com/stretchr/testify.git
displaying mismatch information of arguments diff while panic for closest function call. closes #556
parent
be8372ae8e
commit
7538ed3e89
26
mock/mock.go
26
mock/mock.go
|
@ -249,14 +249,15 @@ func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *
|
|||
return -1, nil
|
||||
}
|
||||
|
||||
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
|
||||
diffCount := 0
|
||||
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (*Call, string) {
|
||||
var diffCount, tempDiffCount int
|
||||
var closestCall *Call
|
||||
var errInfo string
|
||||
|
||||
for _, call := range m.expectedCalls() {
|
||||
if call.Method == method {
|
||||
|
||||
_, tempDiffCount := call.Arguments.Diff(arguments)
|
||||
errInfo, tempDiffCount = call.Arguments.Diff(arguments)
|
||||
if tempDiffCount < diffCount || diffCount == 0 {
|
||||
diffCount = tempDiffCount
|
||||
closestCall = call
|
||||
|
@ -265,11 +266,7 @@ func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *
|
|||
}
|
||||
}
|
||||
|
||||
if closestCall == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, closestCall
|
||||
return closestCall, errInfo
|
||||
}
|
||||
|
||||
func callString(method string, arguments Arguments, includeArgumentValues bool) string {
|
||||
|
@ -316,6 +313,7 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
|
|||
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
|
||||
func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
|
||||
m.mutex.Lock()
|
||||
//TODO: could combine expected and closes in single loop
|
||||
found, call := m.findExpectedCall(methodName, arguments...)
|
||||
|
||||
if found < 0 {
|
||||
|
@ -326,11 +324,16 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
|||
// b) the arguments are not what was expected, or
|
||||
// c) the developer has forgotten to add an accompanying On...Return pair.
|
||||
|
||||
closestFound, closestCall := m.findClosestCall(methodName, arguments...)
|
||||
closestCall, mismatch := m.findClosestCall(methodName, arguments...)
|
||||
m.mutex.Unlock()
|
||||
|
||||
if closestFound {
|
||||
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)))
|
||||
if closestCall != nil {
|
||||
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",
|
||||
callString(methodName, arguments, true),
|
||||
callString(methodName, closestCall.Arguments, true),
|
||||
diffArguments(closestCall.Arguments, arguments),
|
||||
strings.TrimSpace(mismatch)),
|
||||
)
|
||||
} else {
|
||||
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()))
|
||||
}
|
||||
|
@ -604,6 +607,7 @@ func (args Arguments) Is(objects ...interface{}) bool {
|
|||
//
|
||||
// Returns the diff string and number of differences found.
|
||||
func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
//TODO: could return string as error and nil for No difference
|
||||
|
||||
var output = "\n"
|
||||
var differences int
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"runtime"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -1384,6 +1385,43 @@ func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestArgumentMatcherToPrintMismatch(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
matchingExp := regexp.MustCompile(
|
||||
`\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`)
|
||||
assert.Regexp(t, matchingExp, r)
|
||||
}
|
||||
}()
|
||||
|
||||
m := new(timer)
|
||||
m.On("GetTime", MatchedBy(func(i int) bool { return false })).Return("SomeTime").Once()
|
||||
|
||||
res := m.GetTime(1)
|
||||
require.Equal(t, "SomeTime", res)
|
||||
m.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestClosestCallMismatchedArgumentValueInformation(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
matchingExp := regexp.MustCompile(unexpectedCallRegex(`GetTime(int)`, "1", "999", `0: FAIL: %!s(int=1) != %!s(int=999)`))
|
||||
assert.Regexp(t, matchingExp, r)
|
||||
}
|
||||
}()
|
||||
|
||||
m := new(timer)
|
||||
m.On("GetTime", 999).Return("SomeTime").Once()
|
||||
|
||||
_ = m.GetTime(1)
|
||||
}
|
||||
|
||||
func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
|
||||
rMethod := regexp.QuoteMeta(method)
|
||||
return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+0: %s\s+The closest call I have is:\s+%s\s+0: %s\s+Diff: %s`,
|
||||
rMethod, regexp.QuoteMeta(calledArg), rMethod, regexp.QuoteMeta(expectedArg), regexp.QuoteMeta(diff))
|
||||
}
|
||||
|
||||
func ConcurrencyTestMethod(m *Mock) {
|
||||
m.Called()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue