diff --git a/gomock/call.go b/gomock/call.go index e1fe222..a00316e 100644 --- a/gomock/call.go +++ b/gomock/call.go @@ -498,7 +498,12 @@ func (c *Call) addAction(action func([]any) []any) { } func formatGottenArg(m Matcher, arg any) string { - got := fmt.Sprintf("%v (%T)", arg, arg) + var got string + if v := reflect.ValueOf(arg); v.Kind() == reflect.Slice && v.IsNil() { + got = fmt.Sprintf("nil (%T)", arg) + } else { + got = fmt.Sprintf("%v (%T)", arg, arg) + } if gs, ok := m.(GotFormatter); ok { got = gs.Got(arg) } diff --git a/gomock/controller_test.go b/gomock/controller_test.go index 7e0397d..a8947ae 100644 --- a/gomock/controller_test.go +++ b/gomock/controller_test.go @@ -159,6 +159,8 @@ func (s *Subject) ActOnTestStructMethod(arg TestStruct, arg1 int) int { func (s *Subject) SetArgMethod(sliceArg []byte, ptrArg *int, mapArg map[any]any) {} func (s *Subject) SetArgMethodInterface(sliceArg, ptrArg, mapArg any) {} +func (s *Subject) SliceArgMethod(arg []byte) {} +func (s *Subject) SliceOfArraysMethod(arg [][32]byte) {} func assertEqual(t *testing.T, expected any, actual any) { if !reflect.DeepEqual(expected, actual) { @@ -622,6 +624,48 @@ func TestSetArgPtr(t *testing.T) { } } +func TestNilSliceVsEmptySlice(t *testing.T) { + reporter, ctrl := createFixtures(t) + defer reporter.recoverUnexpectedFatal() + subject := new(Subject) + + ctrl.RecordCall(subject, "SliceArgMethod", []byte{}) + + var nilSlice []byte + reporter.assertFatal(func() { + // Calling with a nil slice should fail, but error message should clearly + // distinguish nil from empty slice (issue #69). + ctrl.Call(subject, "SliceArgMethod", nilSlice) + }, "Unexpected call to", "doesn't match the argument at index 0", + "Got: nil ([]uint8)\nWant: is equal to [] ([]uint8)") + + reporter.assertFatal(func() { + // The expected call wasn't made. + ctrl.Finish() + }) +} + +func TestNilSliceOfArraysVsEmpty(t *testing.T) { + reporter, ctrl := createFixtures(t) + defer reporter.recoverUnexpectedFatal() + subject := new(Subject) + + ctrl.RecordCall(subject, "SliceOfArraysMethod", [][32]byte{}) + + var nilSlice [][32]byte + reporter.assertFatal(func() { + // Reproduce the exact scenario from issue #69: nil vs empty [][32]byte. + // Before the fix, both would show as "[]" making them indistinguishable. + ctrl.Call(subject, "SliceOfArraysMethod", nilSlice) + }, "Unexpected call to", "doesn't match the argument at index 0", + "Got: nil ([][32]uint8)\nWant: is equal to [] ([][32]uint8)") + + reporter.assertFatal(func() { + // The expected call wasn't made. + ctrl.Finish() + }) +} + func TestReturn(t *testing.T) { _, ctrl := createFixtures(t) subject := new(Subject)