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 }