Repository: stretchr/testify (go)

Issue:
Release 1.7.3 call AssertExpectations without On cause panic
If I call call method `AssertExpectations` without having call the method `On` it panics

panic: runtime error: invalid memory address or nil pointer dereference

I usually have a test structure like the one below: not always I will call `mock.On` to prepare the mock - depends on the case and the preconditions. But I always check if the expectations are correct.

On Release 1.7.3 the mutex field in the Mock struct became a pointer to a mutex. And some methods check if the mutex is nil and initialize, but it is not the case of `AssertExpectations`. In fact this release break all of my test suites.

I note that there is a `Test` method that can initialize it, but I never use it. And the documentation says the test field is optional. Call `Test` seems vague and redundant (what is test? it tests my mock? it set a field to be used?), since I still need to call `AssertExpectations`.

What is the solution? rewrite my test suites or may I submit a patch to initialize the mock? or perhaps I should create a constructor for my mocks that calls mock.Test and prepare it ?

```golang
func TestXxx(t *testing.T) { 
  testcases := []struct {
    label string
    prepare func(*myMockObject)
    ...  
  }{ ... }
 
  for _, tc := range testcases {
    tc := tc
    t.Run(tc.label, func(t *testing.T) {
         m := &myMockObject{}
         defer m.AssertExpectations(t)

         tc.prepare(m)

         // rest of the test
    }
  }
}
```

Pull request:
Fix panic in AssertExpectations for mocks without expectations
## Summary
Regression was introduced in #1182 (released in v1.7.3) which updated the mock mutex to be a pointer and updated _most_ call sites that check this mutex to initialize if it's not yet, however the `mock.AssertExpectationsForObjects` and thus the `mockObject.AssertExpectations` did not take this into account which results in a panic. It's common to initialize mocks at the start of a test and then defer asserting expectations for the end of the test regardless of if a mock had expectations set on it or not. This happens in cases where the test mock does not set any `On()` methods or does not call `mockedObject.Test(t)` which would initialize the mutex if it's not set. Calling `mockedObject.Test(t)` is a fine workaround, but regardless this is a regression.

I added a test case that repro's the issue without the change. I'm happy to update this to be it's own test, but for now, I just left a comment about why it's there.

## Changes
Updates the `mock.AssertExpectationsForObjects` to initialize the mutex if it's not created yet.

## Motivation
<!-- Why were the changes necessary. -->
Regression introduced in #1182 which causes a panic for previously working test code

## Related issues
<!-- Put `Closes #XXXX` for each issue number this PR fixes/closes -->
Closes #1206 


Patch:
diff --git a/mock/mock.go b/mock/mock.go
index 646c9b5..fefc8e9 100644
--- a/mock/mock.go
+++ b/mock/mock.go
@@ -508,6 +508,10 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if m.mutex == nil {
+		m.mutex = &sync.Mutex{}
+	}
+
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
 	var somethingMissing bool


Test patch:
diff --git a/mock/mock_test.go b/mock/mock_test.go
index 91828f8..f8befa8 100644
--- a/mock/mock_test.go
+++ b/mock/mock_test.go
@@ -915,6 +915,7 @@ func Test_AssertExpectationsForObjects_Helper(t *testing.T) {
 	var mockedService1 = new(TestExampleImplementation)
 	var mockedService2 = new(TestExampleImplementation)
 	var mockedService3 = new(TestExampleImplementation)
+	var mockedService4 = new(TestExampleImplementation) // No expectations does not cause a panic
 
 	mockedService1.On("Test_AssertExpectationsForObjects_Helper", 1).Return()
 	mockedService2.On("Test_AssertExpectationsForObjects_Helper", 2).Return()
@@ -924,8 +925,8 @@ func Test_AssertExpectationsForObjects_Helper(t *testing.T) {
 	mockedService2.Called(2)
 	mockedService3.Called(3)
 
-	assert.True(t, AssertExpectationsForObjects(t, &mockedService1.Mock, &mockedService2.Mock, &mockedService3.Mock))
-	assert.True(t, AssertExpectationsForObjects(t, mockedService1, mockedService2, mockedService3))
+	assert.True(t, AssertExpectationsForObjects(t, &mockedService1.Mock, &mockedService2.Mock, &mockedService3.Mock, &mockedService4.Mock))
+	assert.True(t, AssertExpectationsForObjects(t, mockedService1, mockedService2, mockedService3, mockedService4))
 
 }