diff --git a/mock/mock.go b/mock/mock.go index e6ff8dfeb..431445393 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -886,7 +886,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { actualFmt = "(Missing)" } else { actual = objects[i] - actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual) + actualFmt = fmt.Sprintf("(%[1]T=%[1]p)", actual) } if len(args) <= i { @@ -894,7 +894,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { expectedFmt = "(Missing)" } else { expected = args[i] - expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected) + expectedFmt = fmt.Sprintf("(%[1]T=%[1]p)", expected) } if matcher, ok := expected.(argumentMatcher); ok { diff --git a/mock/mock_test.go b/mock/mock_test.go index 260bb9c4f..6157ba9c2 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -1847,6 +1847,41 @@ func Test_MockReturnAndCalledConcurrent(t *testing.T) { wg.Wait() } +// Test to validate fix for racy concurrent value access in MethodCalled() +func Test_MockRunAndCalledConcurrent(t *testing.T) { + type argType struct { + Value int + } + + arg := argType{} + + iterations := 1000 + m := &Mock{} + call := m.On("ConcurrencyTestMethod", Anything) + + wg := sync.WaitGroup{} + wg.Add(2) + + go func() { + for i := 0; i < iterations; i++ { + call.Run(func(args Arguments) { + u := args.Get(2).(*argType) + // u.mu.Lock() + u.Value = 2 + // u.mu.Unlock() + }) + } + wg.Done() + }() + go func() { + for i := 0; i < iterations; i++ { + m.Called(arg) + } + wg.Done() + }() + wg.Wait() +} + type timer struct{ Mock } func (s *timer) GetTime(i int) string {