Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions mock/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,8 @@ type AnythingOfTypeArgument = anythingOfTypeArgument
type anythingOfTypeArgument string

// AnythingOfType returns a special value containing the
// name of the type to check for. The type name will be matched against the type name returned by [reflect.Type.String].
// name of the type to check for. The type name will be matched against the type
// name returned by [reflect.Type.String], or against "<nil>" for nil type .
//
// Used in Diff and Assert.
//
Expand Down Expand Up @@ -1007,10 +1008,16 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
switch expected := expected.(type) {
case anythingOfTypeArgument:
// type checking
if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) {
actualTypeName := "<nil>"
actualTypeString := "<nil>"
if actual != nil {
actualTypeName = reflect.TypeOf(actual).Name()
actualTypeString = reflect.TypeOf(actual).String()
}
if actualTypeName != string(expected) && actualTypeString != string(expected) {
// not match
differences++
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, actualTypeName, actualFmt)
}
case *IsTypeArgument:
actualT := reflect.TypeOf(actual)
Expand Down
117 changes: 109 additions & 8 deletions mock/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,20 +131,21 @@ func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType)

// MockTestingT mocks a test struct
type MockTestingT struct {
logfCount, errorfCount, failNowCount int
logfMessages, errorfMessages []string
failNowCount int
}

// Helper is like [testing.T.Helper] but does nothing.
func (MockTestingT) Helper() {}

const mockTestingTFailNowCalled = "FailNow was called"

func (m *MockTestingT) Logf(string, ...interface{}) {
m.logfCount++
func (m *MockTestingT) Logf(format string, a ...interface{}) {
m.logfMessages = append(m.logfMessages, fmt.Sprintf(format, a...))
}

func (m *MockTestingT) Errorf(string, ...interface{}) {
m.errorfCount++
func (m *MockTestingT) Errorf(format string, a ...interface{}) {
m.errorfMessages = append(m.errorfMessages, fmt.Sprintf(format, a...))
}

// FailNow mocks the FailNow call.
Expand Down Expand Up @@ -324,7 +325,7 @@ func TestMock_WithTest(t *testing.T) {
mockedService.TheExampleMethod(1, 2, 3)

// Assert that Errorf and FailNow were not called
assert.Equal(t, 0, mockedTest.errorfCount)
assert.Equal(t, 0, len(mockedTest.errorfMessages))
assert.Equal(t, 0, mockedTest.failNowCount)

// Test that on unexpected call, the mocked test was called to fail the test
Expand All @@ -334,7 +335,7 @@ func TestMock_WithTest(t *testing.T) {
})

// Assert that Errorf and FailNow were called once
assert.Equal(t, 1, mockedTest.errorfCount)
assert.Equal(t, 1, len(mockedTest.errorfMessages))
assert.Equal(t, 1, mockedTest.failNowCount)
}

Expand Down Expand Up @@ -2465,5 +2466,105 @@ func TestIssue1785ArgumentWithMutatingStringer(t *testing.T) {
func TestIssue1227AssertExpectationsForObjectsWithMock(t *testing.T) {
mockT := &MockTestingT{}
AssertExpectationsForObjects(mockT, Mock{})
assert.Equal(t, 1, mockT.errorfCount)
assert.Equal(t, 1, len(mockT.errorfMessages))
}

func TestIssue1209AnythingOfTypeNilAsString(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", AnythingOfType("string")).Return()
assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
m.MethodCalled("Fn", nil)
})
require.Len(t, mockT.errorfMessages, 1)
require.Contains(t, mockT.errorfMessages[0], "Diff: 0: FAIL: type string != type <nil> - (<nil>=<nil>)")
}

func TestIssue1209AnythingOfTypeStringAsNil(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", AnythingOfType("<nil>")).Return()
assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
m.MethodCalled("Fn", "")
})
require.Len(t, mockT.errorfMessages, 1)
require.Contains(t, mockT.errorfMessages[0], "Diff: 0: FAIL: type <nil> != type string - (string=)")
}

func TestIssue1209AnythingOfTypeNilAsNil(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", AnythingOfType("<nil>")).Return()
assert.NotPanics(t, func() {
m.MethodCalled("Fn", nil)
})
}

func TestIssue1209AnythingOfTypeStringAsEmptyString(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", AnythingOfType("")).Return()
assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
m.MethodCalled("Fn", "my lovely string")
})
require.Len(t, mockT.errorfMessages, 1)
require.Contains(t, mockT.errorfMessages[0], "Diff: 0: FAIL: type != type string - (string=my lovely string)")
}

func TestIssue1209AnythingOfTypeNilAsEmptyString(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", AnythingOfType("")).Return()
assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
m.MethodCalled("Fn", nil)
})
require.Len(t, mockT.errorfMessages, 1)
require.Contains(t, mockT.errorfMessages[0], "Diff: 0: FAIL: type != type <nil> - (<nil>=<nil>)")
}

func TestIssue1209IsTypeNilAsString(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", IsType("")).Return()
assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
m.MethodCalled("Fn", nil)
})
require.Len(t, mockT.errorfMessages, 1)
require.Contains(t, mockT.errorfMessages[0], "Diff: 0: FAIL: type string != type <nil> - (<nil>=<nil>)")
}

func TestIssue1209IsTypeStringAsNil(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", IsType(nil)).Return()
assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
m.MethodCalled("Fn", "")
})
require.Len(t, mockT.errorfMessages, 1)
require.Contains(t, mockT.errorfMessages[0], "Diff: 0: FAIL: type <nil> != type string - (string=)")
}

func TestIssue1209IsTypeNilAsNil(t *testing.T) {
t.Parallel()
mockT := &MockTestingT{}
m := &Mock{}
m.Test(mockT)
m.On("Fn", IsType(nil)).Return()
assert.NotPanics(t, func() {
m.MethodCalled("Fn", nil)
})
}