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
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
|
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (*Call, string) {
|
||||||
diffCount := 0
|
var diffCount, tempDiffCount int
|
||||||
var closestCall *Call
|
var closestCall *Call
|
||||||
|
var errInfo string
|
||||||
|
|
||||||
for _, call := range m.expectedCalls() {
|
for _, call := range m.expectedCalls() {
|
||||||
if call.Method == method {
|
if call.Method == method {
|
||||||
|
|
||||||
_, tempDiffCount := call.Arguments.Diff(arguments)
|
errInfo, tempDiffCount = call.Arguments.Diff(arguments)
|
||||||
if tempDiffCount < diffCount || diffCount == 0 {
|
if tempDiffCount < diffCount || diffCount == 0 {
|
||||||
diffCount = tempDiffCount
|
diffCount = tempDiffCount
|
||||||
closestCall = call
|
closestCall = call
|
||||||
|
@ -265,11 +266,7 @@ func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if closestCall == nil {
|
return closestCall, errInfo
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, closestCall
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func callString(method string, arguments Arguments, includeArgumentValues bool) string {
|
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.
|
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
|
||||||
func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
|
func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
|
//TODO: could combine expected and closes in single loop
|
||||||
found, call := m.findExpectedCall(methodName, arguments...)
|
found, call := m.findExpectedCall(methodName, arguments...)
|
||||||
|
|
||||||
if found < 0 {
|
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
|
// b) the arguments are not what was expected, or
|
||||||
// c) the developer has forgotten to add an accompanying On...Return pair.
|
// 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()
|
m.mutex.Unlock()
|
||||||
|
|
||||||
if closestFound {
|
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\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(closestCall.Arguments, arguments)))
|
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 {
|
} 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()))
|
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.
|
// Returns the diff string and number of differences found.
|
||||||
func (args Arguments) Diff(objects []interface{}) (string, int) {
|
func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||||
|
//TODO: could return string as error and nil for No difference
|
||||||
|
|
||||||
var output = "\n"
|
var output = "\n"
|
||||||
var differences int
|
var differences int
|
||||||
|
|
|
@ -8,9 +8,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func ConcurrencyTestMethod(m *Mock) {
|
||||||
m.Called()
|
m.Called()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue