github.com/golang/mock@v1.6.0/gomock/controller_test.go (about)

     1  // Copyright 2011 Google Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package gomock_test
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  	"testing"
    21  
    22  	"strings"
    23  
    24  	"github.com/golang/mock/gomock"
    25  )
    26  
    27  type ErrorReporter struct {
    28  	t          *testing.T
    29  	log        []string
    30  	failed     bool
    31  	fatalToken struct{}
    32  }
    33  
    34  func NewErrorReporter(t *testing.T) *ErrorReporter {
    35  	return &ErrorReporter{t: t}
    36  }
    37  
    38  func (e *ErrorReporter) reportLog() {
    39  	for _, entry := range e.log {
    40  		e.t.Log(entry)
    41  	}
    42  }
    43  
    44  func (e *ErrorReporter) assertPass(msg string) {
    45  	if e.failed {
    46  		e.t.Errorf("Expected pass, but got failure(s): %s", msg)
    47  		e.reportLog()
    48  	}
    49  }
    50  
    51  func (e *ErrorReporter) assertFail(msg string) {
    52  	if !e.failed {
    53  		e.t.Errorf("Expected failure, but got pass: %s", msg)
    54  	}
    55  }
    56  
    57  // Use to check that code triggers a fatal test failure.
    58  func (e *ErrorReporter) assertFatal(fn func(), expectedErrMsgs ...string) {
    59  	defer func() {
    60  		err := recover()
    61  		if err == nil {
    62  			var actual string
    63  			if e.failed {
    64  				actual = "non-fatal failure"
    65  			} else {
    66  				actual = "pass"
    67  			}
    68  			e.t.Error("Expected fatal failure, but got a", actual)
    69  		} else if token, ok := err.(*struct{}); ok && token == &e.fatalToken {
    70  			// This is okay - the panic is from Fatalf().
    71  			if expectedErrMsgs != nil {
    72  				// assert that the actual error message
    73  				// contains expectedErrMsgs
    74  
    75  				// check the last actualErrMsg, because the previous messages come from previous errors
    76  				actualErrMsg := e.log[len(e.log)-1]
    77  				for _, expectedErrMsg := range expectedErrMsgs {
    78  					if !strings.Contains(actualErrMsg, expectedErrMsg) {
    79  						e.t.Errorf("Error message:\ngot: %q\nwant to contain: %q\n", actualErrMsg, expectedErrMsg)
    80  					}
    81  				}
    82  			}
    83  			return
    84  		} else {
    85  			// Some other panic.
    86  			panic(err)
    87  		}
    88  	}()
    89  
    90  	fn()
    91  }
    92  
    93  // recoverUnexpectedFatal can be used as a deferred call in test cases to
    94  // recover from and display a call to ErrorReporter.Fatalf().
    95  func (e *ErrorReporter) recoverUnexpectedFatal() {
    96  	err := recover()
    97  	if err == nil {
    98  		// No panic.
    99  	} else if token, ok := err.(*struct{}); ok && token == &e.fatalToken {
   100  		// Unexpected fatal error happened.
   101  		e.t.Error("Got unexpected fatal error(s). All errors up to this point:")
   102  		e.reportLog()
   103  		return
   104  	} else {
   105  		// Some other panic.
   106  		panic(err)
   107  	}
   108  }
   109  
   110  func (e *ErrorReporter) Log(args ...interface{}) {
   111  	e.log = append(e.log, fmt.Sprint(args...))
   112  }
   113  
   114  func (e *ErrorReporter) Logf(format string, args ...interface{}) {
   115  	e.log = append(e.log, fmt.Sprintf(format, args...))
   116  }
   117  
   118  func (e *ErrorReporter) Errorf(format string, args ...interface{}) {
   119  	e.Logf(format, args...)
   120  	e.failed = true
   121  }
   122  
   123  func (e *ErrorReporter) Fatalf(format string, args ...interface{}) {
   124  	e.Logf(format, args...)
   125  	e.failed = true
   126  	panic(&e.fatalToken)
   127  }
   128  
   129  type HelperReporter struct {
   130  	gomock.TestReporter
   131  	helper int
   132  }
   133  
   134  func (h *HelperReporter) Helper() {
   135  	h.helper++
   136  }
   137  
   138  // A type purely for use as a receiver in testing the Controller.
   139  type Subject struct{}
   140  
   141  func (s *Subject) FooMethod(arg string) int {
   142  	return 0
   143  }
   144  
   145  func (s *Subject) BarMethod(arg string) int {
   146  	return 0
   147  }
   148  
   149  func (s *Subject) VariadicMethod(arg int, vararg ...string) {}
   150  
   151  // A type purely for ActOnTestStructMethod
   152  type TestStruct struct {
   153  	Number  int
   154  	Message string
   155  }
   156  
   157  func (s *Subject) ActOnTestStructMethod(arg TestStruct, arg1 int) int {
   158  	return 0
   159  }
   160  
   161  func (s *Subject) SetArgMethod(sliceArg []byte, ptrArg *int) {}
   162  
   163  func assertEqual(t *testing.T, expected interface{}, actual interface{}) {
   164  	if !reflect.DeepEqual(expected, actual) {
   165  		t.Errorf("Expected %+v, but got %+v", expected, actual)
   166  	}
   167  }
   168  
   169  func createFixtures(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller) {
   170  	// reporter acts as a testing.T-like object that we pass to the
   171  	// Controller. We use it to test that the mock considered tests
   172  	// successful or failed.
   173  	reporter = NewErrorReporter(t)
   174  	ctrl = gomock.NewController(reporter)
   175  	return
   176  }
   177  
   178  func TestNoCalls(t *testing.T) {
   179  	reporter, ctrl := createFixtures(t)
   180  	ctrl.Finish()
   181  	reporter.assertPass("No calls expected or made.")
   182  }
   183  
   184  func TestNoRecordedCallsForAReceiver(t *testing.T) {
   185  	reporter, ctrl := createFixtures(t)
   186  	subject := new(Subject)
   187  
   188  	reporter.assertFatal(func() {
   189  		ctrl.Call(subject, "NotRecordedMethod", "argument")
   190  	}, "Unexpected call to", "there are no expected calls of the method \"NotRecordedMethod\" for that receiver")
   191  	ctrl.Finish()
   192  }
   193  
   194  func TestNoRecordedMatchingMethodNameForAReceiver(t *testing.T) {
   195  	reporter, ctrl := createFixtures(t)
   196  	subject := new(Subject)
   197  
   198  	ctrl.RecordCall(subject, "FooMethod", "argument")
   199  	reporter.assertFatal(func() {
   200  		ctrl.Call(subject, "NotRecordedMethod", "argument")
   201  	}, "Unexpected call to", "there are no expected calls of the method \"NotRecordedMethod\" for that receiver")
   202  	reporter.assertFatal(func() {
   203  		// The expected call wasn't made.
   204  		ctrl.Finish()
   205  	})
   206  }
   207  
   208  // This tests that a call with an arguments of some primitive type matches a recorded call.
   209  func TestExpectedMethodCall(t *testing.T) {
   210  	reporter, ctrl := createFixtures(t)
   211  	subject := new(Subject)
   212  
   213  	ctrl.RecordCall(subject, "FooMethod", "argument")
   214  	ctrl.Call(subject, "FooMethod", "argument")
   215  	ctrl.Finish()
   216  
   217  	reporter.assertPass("Expected method call made.")
   218  }
   219  
   220  func TestUnexpectedMethodCall(t *testing.T) {
   221  	reporter, ctrl := createFixtures(t)
   222  	subject := new(Subject)
   223  
   224  	reporter.assertFatal(func() {
   225  		ctrl.Call(subject, "FooMethod", "argument")
   226  	})
   227  
   228  	ctrl.Finish()
   229  }
   230  
   231  func TestRepeatedCall(t *testing.T) {
   232  	reporter, ctrl := createFixtures(t)
   233  	subject := new(Subject)
   234  
   235  	ctrl.RecordCall(subject, "FooMethod", "argument").Times(3)
   236  	ctrl.Call(subject, "FooMethod", "argument")
   237  	ctrl.Call(subject, "FooMethod", "argument")
   238  	ctrl.Call(subject, "FooMethod", "argument")
   239  	reporter.assertPass("After expected repeated method calls.")
   240  	reporter.assertFatal(func() {
   241  		ctrl.Call(subject, "FooMethod", "argument")
   242  	})
   243  	ctrl.Finish()
   244  	reporter.assertFail("After calling one too many times.")
   245  }
   246  
   247  func TestUnexpectedArgCount(t *testing.T) {
   248  	reporter, ctrl := createFixtures(t)
   249  	defer reporter.recoverUnexpectedFatal()
   250  	subject := new(Subject)
   251  
   252  	ctrl.RecordCall(subject, "FooMethod", "argument")
   253  	reporter.assertFatal(func() {
   254  		// This call is made with the wrong number of arguments...
   255  		ctrl.Call(subject, "FooMethod", "argument", "extra_argument")
   256  	}, "Unexpected call to", "wrong number of arguments", "Got: 2, want: 1")
   257  	reporter.assertFatal(func() {
   258  		// ... so is this.
   259  		ctrl.Call(subject, "FooMethod")
   260  	}, "Unexpected call to", "wrong number of arguments", "Got: 0, want: 1")
   261  	reporter.assertFatal(func() {
   262  		// The expected call wasn't made.
   263  		ctrl.Finish()
   264  	})
   265  }
   266  
   267  // This tests that a call with complex arguments (a struct and some primitive type) matches a recorded call.
   268  func TestExpectedMethodCall_CustomStruct(t *testing.T) {
   269  	reporter, ctrl := createFixtures(t)
   270  	subject := new(Subject)
   271  
   272  	expectedArg0 := TestStruct{Number: 123, Message: "hello"}
   273  	ctrl.RecordCall(subject, "ActOnTestStructMethod", expectedArg0, 15)
   274  	ctrl.Call(subject, "ActOnTestStructMethod", expectedArg0, 15)
   275  
   276  	reporter.assertPass("Expected method call made.")
   277  }
   278  
   279  func TestUnexpectedArgValue_FirstArg(t *testing.T) {
   280  	reporter, ctrl := createFixtures(t)
   281  	defer reporter.recoverUnexpectedFatal()
   282  	subject := new(Subject)
   283  
   284  	expectedArg0 := TestStruct{Number: 123, Message: "hello %s"}
   285  	ctrl.RecordCall(subject, "ActOnTestStructMethod", expectedArg0, 15)
   286  
   287  	reporter.assertFatal(func() {
   288  		// the method argument (of TestStruct type) has 1 unexpected value (for the Message field)
   289  		ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 123, Message: "no message"}, 15)
   290  	}, "Unexpected call to", "doesn't match the argument at index 0",
   291  		"Got: {123 no message} (gomock_test.TestStruct)\nWant: is equal to {123 hello %s} (gomock_test.TestStruct)")
   292  
   293  	reporter.assertFatal(func() {
   294  		// the method argument (of TestStruct type) has 2 unexpected values (for both fields)
   295  		ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 11, Message: "no message"}, 15)
   296  	}, "Unexpected call to", "doesn't match the argument at index 0",
   297  		"Got: {11 no message} (gomock_test.TestStruct)\nWant: is equal to {123 hello %s} (gomock_test.TestStruct)")
   298  
   299  	reporter.assertFatal(func() {
   300  		// The expected call wasn't made.
   301  		ctrl.Finish()
   302  	})
   303  }
   304  
   305  func TestUnexpectedArgValue_SecondArg(t *testing.T) {
   306  	reporter, ctrl := createFixtures(t)
   307  	defer reporter.recoverUnexpectedFatal()
   308  	subject := new(Subject)
   309  
   310  	expectedArg0 := TestStruct{Number: 123, Message: "hello"}
   311  	ctrl.RecordCall(subject, "ActOnTestStructMethod", expectedArg0, 15)
   312  
   313  	reporter.assertFatal(func() {
   314  		ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 123, Message: "hello"}, 3)
   315  	}, "Unexpected call to", "doesn't match the argument at index 1",
   316  		"Got: 3 (int)\nWant: is equal to 15 (int)")
   317  
   318  	reporter.assertFatal(func() {
   319  		// The expected call wasn't made.
   320  		ctrl.Finish()
   321  	})
   322  }
   323  
   324  func TestUnexpectedArgValue_WantFormatter(t *testing.T) {
   325  	reporter, ctrl := createFixtures(t)
   326  	defer reporter.recoverUnexpectedFatal()
   327  	subject := new(Subject)
   328  
   329  	expectedArg0 := TestStruct{Number: 123, Message: "hello"}
   330  	ctrl.RecordCall(
   331  		subject,
   332  		"ActOnTestStructMethod",
   333  		expectedArg0,
   334  		gomock.WantFormatter(
   335  			gomock.StringerFunc(func() string { return "is equal to fifteen" }),
   336  			gomock.Eq(15),
   337  		),
   338  	)
   339  
   340  	reporter.assertFatal(func() {
   341  		ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 123, Message: "hello"}, 3)
   342  	}, "Unexpected call to", "doesn't match the argument at index 1",
   343  		"Got: 3 (int)\nWant: is equal to fifteen")
   344  
   345  	reporter.assertFatal(func() {
   346  		// The expected call wasn't made.
   347  		ctrl.Finish()
   348  	})
   349  }
   350  
   351  func TestUnexpectedArgValue_GotFormatter(t *testing.T) {
   352  	reporter, ctrl := createFixtures(t)
   353  	defer reporter.recoverUnexpectedFatal()
   354  	subject := new(Subject)
   355  
   356  	expectedArg0 := TestStruct{Number: 123, Message: "hello"}
   357  	ctrl.RecordCall(
   358  		subject,
   359  		"ActOnTestStructMethod",
   360  		expectedArg0,
   361  		gomock.GotFormatterAdapter(
   362  			gomock.GotFormatterFunc(func(i interface{}) string {
   363  				// Leading 0s
   364  				return fmt.Sprintf("%02d", i)
   365  			}),
   366  			gomock.Eq(15),
   367  		),
   368  	)
   369  
   370  	reporter.assertFatal(func() {
   371  		ctrl.Call(subject, "ActOnTestStructMethod", TestStruct{Number: 123, Message: "hello"}, 3)
   372  	}, "Unexpected call to", "doesn't match the argument at index 1",
   373  		"Got: 03\nWant: is equal to 15")
   374  
   375  	reporter.assertFatal(func() {
   376  		// The expected call wasn't made.
   377  		ctrl.Finish()
   378  	})
   379  }
   380  
   381  func TestAnyTimes(t *testing.T) {
   382  	reporter, ctrl := createFixtures(t)
   383  	subject := new(Subject)
   384  
   385  	ctrl.RecordCall(subject, "FooMethod", "argument").AnyTimes()
   386  	for i := 0; i < 100; i++ {
   387  		ctrl.Call(subject, "FooMethod", "argument")
   388  	}
   389  	reporter.assertPass("After 100 method calls.")
   390  	ctrl.Finish()
   391  }
   392  
   393  func TestMinTimes1(t *testing.T) {
   394  	// It fails if there are no calls
   395  	reporter, ctrl := createFixtures(t)
   396  	subject := new(Subject)
   397  	ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1)
   398  	reporter.assertFatal(func() {
   399  		ctrl.Finish()
   400  	})
   401  
   402  	// It succeeds if there is one call
   403  	_, ctrl = createFixtures(t)
   404  	subject = new(Subject)
   405  	ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1)
   406  	ctrl.Call(subject, "FooMethod", "argument")
   407  	ctrl.Finish()
   408  
   409  	// It succeeds if there are many calls
   410  	_, ctrl = createFixtures(t)
   411  	subject = new(Subject)
   412  	ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1)
   413  	for i := 0; i < 100; i++ {
   414  		ctrl.Call(subject, "FooMethod", "argument")
   415  	}
   416  	ctrl.Finish()
   417  }
   418  
   419  func TestMaxTimes1(t *testing.T) {
   420  	// It succeeds if there are no calls
   421  	_, ctrl := createFixtures(t)
   422  	subject := new(Subject)
   423  	ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1)
   424  	ctrl.Finish()
   425  
   426  	// It succeeds if there is one call
   427  	_, ctrl = createFixtures(t)
   428  	subject = new(Subject)
   429  	ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1)
   430  	ctrl.Call(subject, "FooMethod", "argument")
   431  	ctrl.Finish()
   432  
   433  	// It fails if there are more
   434  	reporter, ctrl := createFixtures(t)
   435  	subject = new(Subject)
   436  	ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1)
   437  	ctrl.Call(subject, "FooMethod", "argument")
   438  	reporter.assertFatal(func() {
   439  		ctrl.Call(subject, "FooMethod", "argument")
   440  	})
   441  	ctrl.Finish()
   442  }
   443  
   444  func TestMinMaxTimes(t *testing.T) {
   445  	// It fails if there are less calls than specified
   446  	reporter, ctrl := createFixtures(t)
   447  	subject := new(Subject)
   448  	ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2)
   449  	ctrl.Call(subject, "FooMethod", "argument")
   450  	reporter.assertFatal(func() {
   451  		ctrl.Finish()
   452  	})
   453  
   454  	// It fails if there are more calls than specified
   455  	reporter, ctrl = createFixtures(t)
   456  	subject = new(Subject)
   457  	ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2)
   458  	ctrl.Call(subject, "FooMethod", "argument")
   459  	ctrl.Call(subject, "FooMethod", "argument")
   460  	reporter.assertFatal(func() {
   461  		ctrl.Call(subject, "FooMethod", "argument")
   462  	})
   463  
   464  	// It succeeds if there is just the right number of calls
   465  	_, ctrl = createFixtures(t)
   466  	subject = new(Subject)
   467  	ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(2).MinTimes(2)
   468  	ctrl.Call(subject, "FooMethod", "argument")
   469  	ctrl.Call(subject, "FooMethod", "argument")
   470  	ctrl.Finish()
   471  
   472  	// If MaxTimes is called after MinTimes is called with 1, MaxTimes takes precedence.
   473  	reporter, ctrl = createFixtures(t)
   474  	subject = new(Subject)
   475  	ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1).MaxTimes(2)
   476  	ctrl.Call(subject, "FooMethod", "argument")
   477  	ctrl.Call(subject, "FooMethod", "argument")
   478  	reporter.assertFatal(func() {
   479  		ctrl.Call(subject, "FooMethod", "argument")
   480  	})
   481  
   482  	// If MinTimes is called after MaxTimes is called with 1, MinTimes takes precedence.
   483  	_, ctrl = createFixtures(t)
   484  	subject = new(Subject)
   485  	ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1).MinTimes(2)
   486  	for i := 0; i < 100; i++ {
   487  		ctrl.Call(subject, "FooMethod", "argument")
   488  	}
   489  	ctrl.Finish()
   490  }
   491  
   492  func TestDo(t *testing.T) {
   493  	_, ctrl := createFixtures(t)
   494  	subject := new(Subject)
   495  
   496  	doCalled := false
   497  	var argument string
   498  	wantArg := "argument"
   499  	ctrl.RecordCall(subject, "FooMethod", wantArg).Do(
   500  		func(arg string) {
   501  			doCalled = true
   502  			argument = arg
   503  		})
   504  	if doCalled {
   505  		t.Error("Do() callback called too early.")
   506  	}
   507  
   508  	ctrl.Call(subject, "FooMethod", wantArg)
   509  
   510  	if !doCalled {
   511  		t.Error("Do() callback not called.")
   512  	}
   513  	if wantArg != argument {
   514  		t.Error("Do callback received wrong argument.")
   515  	}
   516  
   517  	ctrl.Finish()
   518  }
   519  
   520  func TestDoAndReturn(t *testing.T) {
   521  	_, ctrl := createFixtures(t)
   522  	subject := new(Subject)
   523  
   524  	doCalled := false
   525  	var argument string
   526  	wantArg := "argument"
   527  	ctrl.RecordCall(subject, "FooMethod", wantArg).DoAndReturn(
   528  		func(arg string) int {
   529  			doCalled = true
   530  			argument = arg
   531  			return 5
   532  		})
   533  	if doCalled {
   534  		t.Error("Do() callback called too early.")
   535  	}
   536  
   537  	rets := ctrl.Call(subject, "FooMethod", wantArg)
   538  
   539  	if !doCalled {
   540  		t.Error("Do() callback not called.")
   541  	}
   542  	if wantArg != argument {
   543  		t.Error("Do callback received wrong argument.")
   544  	}
   545  	if len(rets) != 1 {
   546  		t.Fatalf("Return values from Call: got %d, want 1", len(rets))
   547  	}
   548  	if ret, ok := rets[0].(int); !ok {
   549  		t.Fatalf("Return value is not an int")
   550  	} else if ret != 5 {
   551  		t.Errorf("DoAndReturn return value: got %d, want 5", ret)
   552  	}
   553  
   554  	ctrl.Finish()
   555  }
   556  
   557  func TestSetArgSlice(t *testing.T) {
   558  	_, ctrl := createFixtures(t)
   559  	subject := new(Subject)
   560  
   561  	var in = []byte{4, 5, 6}
   562  	var set = []byte{1, 2, 3}
   563  	ctrl.RecordCall(subject, "SetArgMethod", in, nil).SetArg(0, set)
   564  	ctrl.Call(subject, "SetArgMethod", in, nil)
   565  
   566  	if !reflect.DeepEqual(in, set) {
   567  		t.Error("Expected SetArg() to modify input slice argument")
   568  	}
   569  
   570  	ctrl.Finish()
   571  }
   572  
   573  func TestSetArgPtr(t *testing.T) {
   574  	_, ctrl := createFixtures(t)
   575  	subject := new(Subject)
   576  
   577  	var in int = 43
   578  	const set = 42
   579  	ctrl.RecordCall(subject, "SetArgMethod", nil, &in).SetArg(1, set)
   580  	ctrl.Call(subject, "SetArgMethod", nil, &in)
   581  
   582  	if in != set {
   583  		t.Error("Expected SetArg() to modify value pointed to by argument")
   584  	}
   585  
   586  	ctrl.Finish()
   587  }
   588  
   589  func TestReturn(t *testing.T) {
   590  	_, ctrl := createFixtures(t)
   591  	subject := new(Subject)
   592  
   593  	// Unspecified return should produce "zero" result.
   594  	ctrl.RecordCall(subject, "FooMethod", "zero")
   595  	ctrl.RecordCall(subject, "FooMethod", "five").Return(5)
   596  
   597  	assertEqual(
   598  		t,
   599  		[]interface{}{0},
   600  		ctrl.Call(subject, "FooMethod", "zero"))
   601  
   602  	assertEqual(
   603  		t,
   604  		[]interface{}{5},
   605  		ctrl.Call(subject, "FooMethod", "five"))
   606  	ctrl.Finish()
   607  }
   608  
   609  func TestUnorderedCalls(t *testing.T) {
   610  	reporter, ctrl := createFixtures(t)
   611  	defer reporter.recoverUnexpectedFatal()
   612  	subjectTwo := new(Subject)
   613  	subjectOne := new(Subject)
   614  
   615  	ctrl.RecordCall(subjectOne, "FooMethod", "1")
   616  	ctrl.RecordCall(subjectOne, "BarMethod", "2")
   617  	ctrl.RecordCall(subjectTwo, "FooMethod", "3")
   618  	ctrl.RecordCall(subjectTwo, "BarMethod", "4")
   619  
   620  	// Make the calls in a different order, which should be fine.
   621  	ctrl.Call(subjectOne, "BarMethod", "2")
   622  	ctrl.Call(subjectTwo, "FooMethod", "3")
   623  	ctrl.Call(subjectTwo, "BarMethod", "4")
   624  	ctrl.Call(subjectOne, "FooMethod", "1")
   625  
   626  	reporter.assertPass("After making all calls in different order")
   627  
   628  	ctrl.Finish()
   629  
   630  	reporter.assertPass("After finish")
   631  }
   632  
   633  func commonTestOrderedCalls(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller, subjectOne, subjectTwo *Subject) {
   634  	reporter, ctrl = createFixtures(t)
   635  
   636  	subjectOne = new(Subject)
   637  	subjectTwo = new(Subject)
   638  
   639  	gomock.InOrder(
   640  		ctrl.RecordCall(subjectOne, "FooMethod", "1").AnyTimes(),
   641  		ctrl.RecordCall(subjectTwo, "FooMethod", "2"),
   642  		ctrl.RecordCall(subjectTwo, "BarMethod", "3"),
   643  	)
   644  
   645  	return
   646  }
   647  
   648  func TestOrderedCallsCorrect(t *testing.T) {
   649  	reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t)
   650  
   651  	ctrl.Call(subjectOne, "FooMethod", "1")
   652  	ctrl.Call(subjectTwo, "FooMethod", "2")
   653  	ctrl.Call(subjectTwo, "BarMethod", "3")
   654  
   655  	ctrl.Finish()
   656  
   657  	reporter.assertPass("After finish")
   658  }
   659  
   660  func TestPanicOverridesExpectationChecks(t *testing.T) {
   661  	ctrl := gomock.NewController(t)
   662  	reporter := NewErrorReporter(t)
   663  
   664  	reporter.assertFatal(func() {
   665  		ctrl.RecordCall(new(Subject), "FooMethod", "1")
   666  		defer ctrl.Finish()
   667  		reporter.Fatalf("Intentional panic")
   668  	})
   669  }
   670  
   671  func TestSetArgWithBadType(t *testing.T) {
   672  	rep, ctrl := createFixtures(t)
   673  	defer ctrl.Finish()
   674  
   675  	s := new(Subject)
   676  	// This should catch a type error:
   677  	rep.assertFatal(func() {
   678  		ctrl.RecordCall(s, "FooMethod", "1").SetArg(0, "blah")
   679  	})
   680  	ctrl.Call(s, "FooMethod", "1")
   681  }
   682  
   683  func TestTimes0(t *testing.T) {
   684  	rep, ctrl := createFixtures(t)
   685  	defer ctrl.Finish()
   686  
   687  	s := new(Subject)
   688  	ctrl.RecordCall(s, "FooMethod", "arg").Times(0)
   689  	rep.assertFatal(func() {
   690  		ctrl.Call(s, "FooMethod", "arg")
   691  	})
   692  }
   693  
   694  func TestVariadicMatching(t *testing.T) {
   695  	rep, ctrl := createFixtures(t)
   696  	defer rep.recoverUnexpectedFatal()
   697  
   698  	s := new(Subject)
   699  	ctrl.RecordCall(s, "VariadicMethod", 0, "1", "2")
   700  	ctrl.Call(s, "VariadicMethod", 0, "1", "2")
   701  	ctrl.Finish()
   702  	rep.assertPass("variadic matching works")
   703  }
   704  
   705  func TestVariadicNoMatch(t *testing.T) {
   706  	rep, ctrl := createFixtures(t)
   707  	defer rep.recoverUnexpectedFatal()
   708  
   709  	s := new(Subject)
   710  	ctrl.RecordCall(s, "VariadicMethod", 0)
   711  	rep.assertFatal(func() {
   712  		ctrl.Call(s, "VariadicMethod", 1)
   713  	}, "expected call at", "doesn't match the argument at index 0",
   714  		"Got: 1 (int)\nWant: is equal to 0 (int)")
   715  	ctrl.Call(s, "VariadicMethod", 0)
   716  	ctrl.Finish()
   717  }
   718  
   719  func TestVariadicMatchingWithSlice(t *testing.T) {
   720  	testCases := [][]string{
   721  		{"1"},
   722  		{"1", "2"},
   723  	}
   724  	for _, tc := range testCases {
   725  		t.Run(fmt.Sprintf("%d arguments", len(tc)), func(t *testing.T) {
   726  			rep, ctrl := createFixtures(t)
   727  			defer rep.recoverUnexpectedFatal()
   728  
   729  			s := new(Subject)
   730  			ctrl.RecordCall(s, "VariadicMethod", 1, tc)
   731  			args := make([]interface{}, len(tc)+1)
   732  			args[0] = 1
   733  			for i, arg := range tc {
   734  				args[i+1] = arg
   735  			}
   736  			ctrl.Call(s, "VariadicMethod", args...)
   737  			ctrl.Finish()
   738  			rep.assertPass("slices can be used as matchers for variadic arguments")
   739  		})
   740  	}
   741  }
   742  
   743  func TestVariadicArgumentsGotFormatter(t *testing.T) {
   744  	rep, ctrl := createFixtures(t)
   745  	defer rep.recoverUnexpectedFatal()
   746  
   747  	s := new(Subject)
   748  	ctrl.RecordCall(
   749  		s,
   750  		"VariadicMethod",
   751  		gomock.GotFormatterAdapter(
   752  			gomock.GotFormatterFunc(func(i interface{}) string {
   753  				return fmt.Sprintf("test{%v}", i)
   754  			}),
   755  			gomock.Eq(0),
   756  		),
   757  	)
   758  
   759  	rep.assertFatal(func() {
   760  		ctrl.Call(s, "VariadicMethod", 1)
   761  	}, "expected call to", "doesn't match the argument at index 0",
   762  		"Got: test{1}\nWant: is equal to 0")
   763  	ctrl.Call(s, "VariadicMethod", 0)
   764  	ctrl.Finish()
   765  }
   766  
   767  func TestVariadicArgumentsGotFormatterTooManyArgsFailure(t *testing.T) {
   768  	rep, ctrl := createFixtures(t)
   769  	defer rep.recoverUnexpectedFatal()
   770  
   771  	s := new(Subject)
   772  	ctrl.RecordCall(
   773  		s,
   774  		"VariadicMethod",
   775  		0,
   776  		gomock.GotFormatterAdapter(
   777  			gomock.GotFormatterFunc(func(i interface{}) string {
   778  				return fmt.Sprintf("test{%v}", i)
   779  			}),
   780  			gomock.Eq("1"),
   781  		),
   782  	)
   783  
   784  	rep.assertFatal(func() {
   785  		ctrl.Call(s, "VariadicMethod", 0, "2", "3")
   786  	}, "expected call to", "doesn't match the argument at index 1",
   787  		"Got: test{[2 3]}\nWant: is equal to 1")
   788  	ctrl.Call(s, "VariadicMethod", 0, "1")
   789  	ctrl.Finish()
   790  }
   791  
   792  func TestNoHelper(t *testing.T) {
   793  	ctrlNoHelper := gomock.NewController(NewErrorReporter(t))
   794  
   795  	// doesn't panic
   796  	ctrlNoHelper.T.Helper()
   797  }
   798  
   799  func TestWithHelper(t *testing.T) {
   800  	withHelper := &HelperReporter{TestReporter: NewErrorReporter(t)}
   801  	ctrlWithHelper := gomock.NewController(withHelper)
   802  
   803  	ctrlWithHelper.T.Helper()
   804  
   805  	if withHelper.helper == 0 {
   806  		t.Fatal("expected Helper to be invoked")
   807  	}
   808  }