1package mock
2
3import (
4	"errors"
5	"fmt"
6	"regexp"
7	"runtime"
8	"sync"
9	"testing"
10	"time"
11
12	"github.com/stretchr/testify/assert"
13	"github.com/stretchr/testify/require"
14)
15
16/*
17	Test objects
18*/
19
20// ExampleInterface represents an example interface.
21type ExampleInterface interface {
22	TheExampleMethod(a, b, c int) (int, error)
23}
24
25// TestExampleImplementation is a test implementation of ExampleInterface
26type TestExampleImplementation struct {
27	Mock
28}
29
30func (i *TestExampleImplementation) TheExampleMethod(a, b, c int) (int, error) {
31	args := i.Called(a, b, c)
32	return args.Int(0), errors.New("Whoops")
33}
34
35//go:noinline
36func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) {
37	i.Called(yesorno)
38}
39
40type ExampleType struct {
41	ran bool
42}
43
44func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
45	args := i.Called(et)
46	return args.Error(0)
47}
48
49func (i *TestExampleImplementation) TheExampleMethod4(v ExampleInterface) error {
50	args := i.Called(v)
51	return args.Error(0)
52}
53
54func (i *TestExampleImplementation) TheExampleMethod5(ch chan struct{}) error {
55	args := i.Called(ch)
56	return args.Error(0)
57}
58
59func (i *TestExampleImplementation) TheExampleMethod6(m map[string]bool) error {
60	args := i.Called(m)
61	return args.Error(0)
62}
63
64func (i *TestExampleImplementation) TheExampleMethod7(slice []bool) error {
65	args := i.Called(slice)
66	return args.Error(0)
67}
68
69func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error {
70	args := i.Called(fn)
71	return args.Error(0)
72}
73
74func (i *TestExampleImplementation) TheExampleMethodVariadic(a ...int) error {
75	args := i.Called(a)
76	return args.Error(0)
77}
78
79func (i *TestExampleImplementation) TheExampleMethodVariadicInterface(a ...interface{}) error {
80	args := i.Called(a)
81	return args.Error(0)
82}
83
84func (i *TestExampleImplementation) TheExampleMethodMixedVariadic(a int, b ...int) error {
85	args := i.Called(a, b)
86	return args.Error(0)
87}
88
89type ExampleFuncType func(string) error
90
91func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType) error {
92	args := i.Called(fn)
93	return args.Error(0)
94}
95
96// MockTestingT mocks a test struct
97type MockTestingT struct {
98	logfCount, errorfCount, failNowCount int
99}
100
101const mockTestingTFailNowCalled = "FailNow was called"
102
103func (m *MockTestingT) Logf(string, ...interface{}) {
104	m.logfCount++
105}
106
107func (m *MockTestingT) Errorf(string, ...interface{}) {
108	m.errorfCount++
109}
110
111// FailNow mocks the FailNow call.
112// It panics in order to mimic the FailNow behavior in the sense that
113// the execution stops.
114// When expecting this method, the call that invokes it should use the following code:
115//
116//     assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {...})
117func (m *MockTestingT) FailNow() {
118	m.failNowCount++
119
120	// this function should panic now to stop the execution as expected
121	panic(mockTestingTFailNowCalled)
122}
123
124/*
125	Mock
126*/
127
128func Test_Mock_TestData(t *testing.T) {
129
130	var mockedService = new(TestExampleImplementation)
131
132	if assert.NotNil(t, mockedService.TestData()) {
133
134		mockedService.TestData().Set("something", 123)
135		assert.Equal(t, 123, mockedService.TestData().Get("something").Data())
136	}
137}
138
139func Test_Mock_On(t *testing.T) {
140
141	// make a test impl object
142	var mockedService = new(TestExampleImplementation)
143
144	c := mockedService.On("TheExampleMethod")
145	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
146	assert.Equal(t, "TheExampleMethod", c.Method)
147}
148
149func Test_Mock_Chained_On(t *testing.T) {
150	// make a test impl object
151	var mockedService = new(TestExampleImplementation)
152
153	// determine our current line number so we can assert the expected calls callerInfo properly
154	_, _, line, _ := runtime.Caller(0)
155	mockedService.
156		On("TheExampleMethod", 1, 2, 3).
157		Return(0).
158		On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
159		Return(nil)
160
161	expectedCalls := []*Call{
162		{
163			Parent:          &mockedService.Mock,
164			Method:          "TheExampleMethod",
165			Arguments:       []interface{}{1, 2, 3},
166			ReturnArguments: []interface{}{0},
167			callerInfo:      []string{fmt.Sprintf("mock_test.go:%d", line+2)},
168		},
169		{
170			Parent:          &mockedService.Mock,
171			Method:          "TheExampleMethod3",
172			Arguments:       []interface{}{AnythingOfType("*mock.ExampleType")},
173			ReturnArguments: []interface{}{nil},
174			callerInfo:      []string{fmt.Sprintf("mock_test.go:%d", line+4)},
175		},
176	}
177	assert.Equal(t, expectedCalls, mockedService.ExpectedCalls)
178}
179
180func Test_Mock_On_WithArgs(t *testing.T) {
181
182	// make a test impl object
183	var mockedService = new(TestExampleImplementation)
184
185	c := mockedService.On("TheExampleMethod", 1, 2, 3, 4)
186
187	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
188	assert.Equal(t, "TheExampleMethod", c.Method)
189	assert.Equal(t, Arguments{1, 2, 3, 4}, c.Arguments)
190}
191
192func Test_Mock_On_WithFuncArg(t *testing.T) {
193
194	// make a test impl object
195	var mockedService = new(TestExampleImplementation)
196
197	c := mockedService.
198		On("TheExampleMethodFunc", AnythingOfType("func(string) error")).
199		Return(nil)
200
201	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
202	assert.Equal(t, "TheExampleMethodFunc", c.Method)
203	assert.Equal(t, 1, len(c.Arguments))
204	assert.Equal(t, AnythingOfType("func(string) error"), c.Arguments[0])
205
206	fn := func(string) error { return nil }
207
208	assert.NotPanics(t, func() {
209		mockedService.TheExampleMethodFunc(fn)
210	})
211}
212
213func Test_Mock_On_WithIntArgMatcher(t *testing.T) {
214	var mockedService TestExampleImplementation
215
216	mockedService.On("TheExampleMethod",
217		MatchedBy(func(a int) bool {
218			return a == 1
219		}), MatchedBy(func(b int) bool {
220			return b == 2
221		}), MatchedBy(func(c int) bool {
222			return c == 3
223		})).Return(0, nil)
224
225	assert.Panics(t, func() {
226		mockedService.TheExampleMethod(1, 2, 4)
227	})
228	assert.Panics(t, func() {
229		mockedService.TheExampleMethod(2, 2, 3)
230	})
231	assert.NotPanics(t, func() {
232		mockedService.TheExampleMethod(1, 2, 3)
233	})
234}
235
236func TestMock_WithTest(t *testing.T) {
237	var (
238		mockedService TestExampleImplementation
239		mockedTest    MockTestingT
240	)
241
242	mockedService.Test(&mockedTest)
243	mockedService.On("TheExampleMethod", 1, 2, 3).Return(0, nil)
244
245	// Test that on an expected call, the test was not failed
246
247	mockedService.TheExampleMethod(1, 2, 3)
248
249	// Assert that Errorf and FailNow were not called
250	assert.Equal(t, 0, mockedTest.errorfCount)
251	assert.Equal(t, 0, mockedTest.failNowCount)
252
253	// Test that on unexpected call, the mocked test was called to fail the test
254
255	assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
256		mockedService.TheExampleMethod(1, 1, 1)
257	})
258
259	// Assert that Errorf and FailNow were called once
260	assert.Equal(t, 1, mockedTest.errorfCount)
261	assert.Equal(t, 1, mockedTest.failNowCount)
262}
263
264func Test_Mock_On_WithPtrArgMatcher(t *testing.T) {
265	var mockedService TestExampleImplementation
266
267	mockedService.On("TheExampleMethod3",
268		MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == true }),
269	).Return(nil)
270
271	mockedService.On("TheExampleMethod3",
272		MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == false }),
273	).Return(errors.New("error"))
274
275	mockedService.On("TheExampleMethod3",
276		MatchedBy(func(a *ExampleType) bool { return a == nil }),
277	).Return(errors.New("error2"))
278
279	assert.Equal(t, mockedService.TheExampleMethod3(&ExampleType{true}), nil)
280	assert.EqualError(t, mockedService.TheExampleMethod3(&ExampleType{false}), "error")
281	assert.EqualError(t, mockedService.TheExampleMethod3(nil), "error2")
282}
283
284func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
285	var mockedService TestExampleImplementation
286
287	fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2")
288
289	mockedService.On("TheExampleMethodFunc",
290		MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture1 }),
291	).Return(errors.New("fixture1"))
292
293	mockedService.On("TheExampleMethodFunc",
294		MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture2 }),
295	).Return(errors.New("fixture2"))
296
297	mockedService.On("TheExampleMethodFunc",
298		MatchedBy(func(a func(string) error) bool { return a == nil }),
299	).Return(errors.New("fixture3"))
300
301	assert.EqualError(t, mockedService.TheExampleMethodFunc(
302		func(string) error { return fixture1 }), "fixture1")
303	assert.EqualError(t, mockedService.TheExampleMethodFunc(
304		func(string) error { return fixture2 }), "fixture2")
305	assert.EqualError(t, mockedService.TheExampleMethodFunc(nil), "fixture3")
306}
307
308func Test_Mock_On_WithInterfaceArgMatcher(t *testing.T) {
309	var mockedService TestExampleImplementation
310
311	mockedService.On("TheExampleMethod4",
312		MatchedBy(func(a ExampleInterface) bool { return a == nil }),
313	).Return(errors.New("fixture1"))
314
315	assert.EqualError(t, mockedService.TheExampleMethod4(nil), "fixture1")
316}
317
318func Test_Mock_On_WithChannelArgMatcher(t *testing.T) {
319	var mockedService TestExampleImplementation
320
321	mockedService.On("TheExampleMethod5",
322		MatchedBy(func(ch chan struct{}) bool { return ch == nil }),
323	).Return(errors.New("fixture1"))
324
325	assert.EqualError(t, mockedService.TheExampleMethod5(nil), "fixture1")
326}
327
328func Test_Mock_On_WithMapArgMatcher(t *testing.T) {
329	var mockedService TestExampleImplementation
330
331	mockedService.On("TheExampleMethod6",
332		MatchedBy(func(m map[string]bool) bool { return m == nil }),
333	).Return(errors.New("fixture1"))
334
335	assert.EqualError(t, mockedService.TheExampleMethod6(nil), "fixture1")
336}
337
338func Test_Mock_On_WithSliceArgMatcher(t *testing.T) {
339	var mockedService TestExampleImplementation
340
341	mockedService.On("TheExampleMethod7",
342		MatchedBy(func(slice []bool) bool { return slice == nil }),
343	).Return(errors.New("fixture1"))
344
345	assert.EqualError(t, mockedService.TheExampleMethod7(nil), "fixture1")
346}
347
348func Test_Mock_On_WithVariadicFunc(t *testing.T) {
349
350	// make a test impl object
351	var mockedService = new(TestExampleImplementation)
352
353	c := mockedService.
354		On("TheExampleMethodVariadic", []int{1, 2, 3}).
355		Return(nil)
356
357	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
358	assert.Equal(t, 1, len(c.Arguments))
359	assert.Equal(t, []int{1, 2, 3}, c.Arguments[0])
360
361	assert.NotPanics(t, func() {
362		mockedService.TheExampleMethodVariadic(1, 2, 3)
363	})
364	assert.Panics(t, func() {
365		mockedService.TheExampleMethodVariadic(1, 2)
366	})
367
368}
369
370func Test_Mock_On_WithMixedVariadicFunc(t *testing.T) {
371
372	// make a test impl object
373	var mockedService = new(TestExampleImplementation)
374
375	c := mockedService.
376		On("TheExampleMethodMixedVariadic", 1, []int{2, 3, 4}).
377		Return(nil)
378
379	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
380	assert.Equal(t, 2, len(c.Arguments))
381	assert.Equal(t, 1, c.Arguments[0])
382	assert.Equal(t, []int{2, 3, 4}, c.Arguments[1])
383
384	assert.NotPanics(t, func() {
385		mockedService.TheExampleMethodMixedVariadic(1, 2, 3, 4)
386	})
387	assert.Panics(t, func() {
388		mockedService.TheExampleMethodMixedVariadic(1, 2, 3, 5)
389	})
390
391}
392
393func Test_Mock_On_WithVariadicFuncWithInterface(t *testing.T) {
394
395	// make a test impl object
396	var mockedService = new(TestExampleImplementation)
397
398	c := mockedService.On("TheExampleMethodVariadicInterface", []interface{}{1, 2, 3}).
399		Return(nil)
400
401	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
402	assert.Equal(t, 1, len(c.Arguments))
403	assert.Equal(t, []interface{}{1, 2, 3}, c.Arguments[0])
404
405	assert.NotPanics(t, func() {
406		mockedService.TheExampleMethodVariadicInterface(1, 2, 3)
407	})
408	assert.Panics(t, func() {
409		mockedService.TheExampleMethodVariadicInterface(1, 2)
410	})
411
412}
413
414func Test_Mock_On_WithVariadicFuncWithEmptyInterfaceArray(t *testing.T) {
415
416	// make a test impl object
417	var mockedService = new(TestExampleImplementation)
418
419	var expected []interface{}
420	c := mockedService.
421		On("TheExampleMethodVariadicInterface", expected).
422		Return(nil)
423
424	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
425	assert.Equal(t, 1, len(c.Arguments))
426	assert.Equal(t, expected, c.Arguments[0])
427
428	assert.NotPanics(t, func() {
429		mockedService.TheExampleMethodVariadicInterface()
430	})
431	assert.Panics(t, func() {
432		mockedService.TheExampleMethodVariadicInterface(1, 2)
433	})
434
435}
436
437func Test_Mock_On_WithFuncPanics(t *testing.T) {
438	// make a test impl object
439	var mockedService = new(TestExampleImplementation)
440
441	assert.Panics(t, func() {
442		mockedService.On("TheExampleMethodFunc", func(string) error { return nil })
443	})
444}
445
446func Test_Mock_On_WithFuncTypeArg(t *testing.T) {
447
448	// make a test impl object
449	var mockedService = new(TestExampleImplementation)
450
451	c := mockedService.
452		On("TheExampleMethodFuncType", AnythingOfType("mock.ExampleFuncType")).
453		Return(nil)
454
455	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
456	assert.Equal(t, 1, len(c.Arguments))
457	assert.Equal(t, AnythingOfType("mock.ExampleFuncType"), c.Arguments[0])
458
459	fn := func(string) error { return nil }
460	assert.NotPanics(t, func() {
461		mockedService.TheExampleMethodFuncType(fn)
462	})
463}
464
465func Test_Mock_Return(t *testing.T) {
466
467	// make a test impl object
468	var mockedService = new(TestExampleImplementation)
469
470	c := mockedService.
471		On("TheExampleMethod", "A", "B", true).
472		Return(1, "two", true)
473
474	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
475
476	call := mockedService.ExpectedCalls[0]
477
478	assert.Equal(t, "TheExampleMethod", call.Method)
479	assert.Equal(t, "A", call.Arguments[0])
480	assert.Equal(t, "B", call.Arguments[1])
481	assert.Equal(t, true, call.Arguments[2])
482	assert.Equal(t, 1, call.ReturnArguments[0])
483	assert.Equal(t, "two", call.ReturnArguments[1])
484	assert.Equal(t, true, call.ReturnArguments[2])
485	assert.Equal(t, 0, call.Repeatability)
486	assert.Nil(t, call.WaitFor)
487}
488
489func Test_Mock_Panic(t *testing.T) {
490
491	// make a test impl object
492	var mockedService = new(TestExampleImplementation)
493
494	c := mockedService.
495		On("TheExampleMethod", "A", "B", true).
496		Panic("panic message for example method")
497
498	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
499
500	call := mockedService.ExpectedCalls[0]
501
502	assert.Equal(t, "TheExampleMethod", call.Method)
503	assert.Equal(t, "A", call.Arguments[0])
504	assert.Equal(t, "B", call.Arguments[1])
505	assert.Equal(t, true, call.Arguments[2])
506	assert.Equal(t, 0, call.Repeatability)
507	assert.Equal(t, 0, call.Repeatability)
508	assert.Equal(t, "panic message for example method", *call.PanicMsg)
509	assert.Nil(t, call.WaitFor)
510}
511
512func Test_Mock_Return_WaitUntil(t *testing.T) {
513
514	// make a test impl object
515	var mockedService = new(TestExampleImplementation)
516	ch := time.After(time.Second)
517
518	c := mockedService.Mock.
519		On("TheExampleMethod", "A", "B", true).
520		WaitUntil(ch).
521		Return(1, "two", true)
522
523	// assert that the call was created
524	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
525
526	call := mockedService.ExpectedCalls[0]
527
528	assert.Equal(t, "TheExampleMethod", call.Method)
529	assert.Equal(t, "A", call.Arguments[0])
530	assert.Equal(t, "B", call.Arguments[1])
531	assert.Equal(t, true, call.Arguments[2])
532	assert.Equal(t, 1, call.ReturnArguments[0])
533	assert.Equal(t, "two", call.ReturnArguments[1])
534	assert.Equal(t, true, call.ReturnArguments[2])
535	assert.Equal(t, 0, call.Repeatability)
536	assert.Equal(t, ch, call.WaitFor)
537}
538
539func Test_Mock_Return_After(t *testing.T) {
540
541	// make a test impl object
542	var mockedService = new(TestExampleImplementation)
543
544	c := mockedService.Mock.
545		On("TheExampleMethod", "A", "B", true).
546		Return(1, "two", true).
547		After(time.Second)
548
549	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
550
551	call := mockedService.Mock.ExpectedCalls[0]
552
553	assert.Equal(t, "TheExampleMethod", call.Method)
554	assert.Equal(t, "A", call.Arguments[0])
555	assert.Equal(t, "B", call.Arguments[1])
556	assert.Equal(t, true, call.Arguments[2])
557	assert.Equal(t, 1, call.ReturnArguments[0])
558	assert.Equal(t, "two", call.ReturnArguments[1])
559	assert.Equal(t, true, call.ReturnArguments[2])
560	assert.Equal(t, 0, call.Repeatability)
561	assert.NotEqual(t, nil, call.WaitFor)
562
563}
564
565func Test_Mock_Return_Run(t *testing.T) {
566
567	// make a test impl object
568	var mockedService = new(TestExampleImplementation)
569
570	fn := func(args Arguments) {
571		arg := args.Get(0).(*ExampleType)
572		arg.ran = true
573	}
574
575	c := mockedService.Mock.
576		On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
577		Return(nil).
578		Run(fn)
579
580	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
581
582	call := mockedService.Mock.ExpectedCalls[0]
583
584	assert.Equal(t, "TheExampleMethod3", call.Method)
585	assert.Equal(t, AnythingOfType("*mock.ExampleType"), call.Arguments[0])
586	assert.Equal(t, nil, call.ReturnArguments[0])
587	assert.Equal(t, 0, call.Repeatability)
588	assert.NotEqual(t, nil, call.WaitFor)
589	assert.NotNil(t, call.Run)
590
591	et := ExampleType{}
592	assert.Equal(t, false, et.ran)
593	mockedService.TheExampleMethod3(&et)
594	assert.Equal(t, true, et.ran)
595}
596
597func Test_Mock_Return_Run_Out_Of_Order(t *testing.T) {
598	// make a test impl object
599	var mockedService = new(TestExampleImplementation)
600	f := func(args Arguments) {
601		arg := args.Get(0).(*ExampleType)
602		arg.ran = true
603	}
604
605	c := mockedService.Mock.
606		On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
607		Run(f).
608		Return(nil)
609
610	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
611
612	call := mockedService.Mock.ExpectedCalls[0]
613
614	assert.Equal(t, "TheExampleMethod3", call.Method)
615	assert.Equal(t, AnythingOfType("*mock.ExampleType"), call.Arguments[0])
616	assert.Equal(t, nil, call.ReturnArguments[0])
617	assert.Equal(t, 0, call.Repeatability)
618	assert.NotEqual(t, nil, call.WaitFor)
619	assert.NotNil(t, call.Run)
620}
621
622func Test_Mock_Return_Once(t *testing.T) {
623
624	// make a test impl object
625	var mockedService = new(TestExampleImplementation)
626
627	c := mockedService.On("TheExampleMethod", "A", "B", true).
628		Return(1, "two", true).
629		Once()
630
631	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
632
633	call := mockedService.ExpectedCalls[0]
634
635	assert.Equal(t, "TheExampleMethod", call.Method)
636	assert.Equal(t, "A", call.Arguments[0])
637	assert.Equal(t, "B", call.Arguments[1])
638	assert.Equal(t, true, call.Arguments[2])
639	assert.Equal(t, 1, call.ReturnArguments[0])
640	assert.Equal(t, "two", call.ReturnArguments[1])
641	assert.Equal(t, true, call.ReturnArguments[2])
642	assert.Equal(t, 1, call.Repeatability)
643	assert.Nil(t, call.WaitFor)
644}
645
646func Test_Mock_Return_Twice(t *testing.T) {
647
648	// make a test impl object
649	var mockedService = new(TestExampleImplementation)
650
651	c := mockedService.
652		On("TheExampleMethod", "A", "B", true).
653		Return(1, "two", true).
654		Twice()
655
656	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
657
658	call := mockedService.ExpectedCalls[0]
659
660	assert.Equal(t, "TheExampleMethod", call.Method)
661	assert.Equal(t, "A", call.Arguments[0])
662	assert.Equal(t, "B", call.Arguments[1])
663	assert.Equal(t, true, call.Arguments[2])
664	assert.Equal(t, 1, call.ReturnArguments[0])
665	assert.Equal(t, "two", call.ReturnArguments[1])
666	assert.Equal(t, true, call.ReturnArguments[2])
667	assert.Equal(t, 2, call.Repeatability)
668	assert.Nil(t, call.WaitFor)
669}
670
671func Test_Mock_Return_Times(t *testing.T) {
672
673	// make a test impl object
674	var mockedService = new(TestExampleImplementation)
675
676	c := mockedService.
677		On("TheExampleMethod", "A", "B", true).
678		Return(1, "two", true).
679		Times(5)
680
681	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
682
683	call := mockedService.ExpectedCalls[0]
684
685	assert.Equal(t, "TheExampleMethod", call.Method)
686	assert.Equal(t, "A", call.Arguments[0])
687	assert.Equal(t, "B", call.Arguments[1])
688	assert.Equal(t, true, call.Arguments[2])
689	assert.Equal(t, 1, call.ReturnArguments[0])
690	assert.Equal(t, "two", call.ReturnArguments[1])
691	assert.Equal(t, true, call.ReturnArguments[2])
692	assert.Equal(t, 5, call.Repeatability)
693	assert.Nil(t, call.WaitFor)
694}
695
696func Test_Mock_Return_Nothing(t *testing.T) {
697
698	// make a test impl object
699	var mockedService = new(TestExampleImplementation)
700
701	c := mockedService.
702		On("TheExampleMethod", "A", "B", true).
703		Return()
704
705	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
706
707	call := mockedService.ExpectedCalls[0]
708
709	assert.Equal(t, "TheExampleMethod", call.Method)
710	assert.Equal(t, "A", call.Arguments[0])
711	assert.Equal(t, "B", call.Arguments[1])
712	assert.Equal(t, true, call.Arguments[2])
713	assert.Equal(t, 0, len(call.ReturnArguments))
714}
715
716func Test_Mock_findExpectedCall(t *testing.T) {
717
718	m := new(Mock)
719	m.On("One", 1).Return("one")
720	m.On("Two", 2).Return("two")
721	m.On("Two", 3).Return("three")
722
723	f, c := m.findExpectedCall("Two", 3)
724
725	if assert.Equal(t, 2, f) {
726		if assert.NotNil(t, c) {
727			assert.Equal(t, "Two", c.Method)
728			assert.Equal(t, 3, c.Arguments[0])
729			assert.Equal(t, "three", c.ReturnArguments[0])
730		}
731	}
732
733}
734
735func Test_Mock_findExpectedCall_For_Unknown_Method(t *testing.T) {
736
737	m := new(Mock)
738	m.On("One", 1).Return("one")
739	m.On("Two", 2).Return("two")
740	m.On("Two", 3).Return("three")
741
742	f, _ := m.findExpectedCall("Two")
743
744	assert.Equal(t, -1, f)
745
746}
747
748func Test_Mock_findExpectedCall_Respects_Repeatability(t *testing.T) {
749
750	m := new(Mock)
751	m.On("One", 1).Return("one")
752	m.On("Two", 2).Return("two").Once()
753	m.On("Two", 3).Return("three").Twice()
754	m.On("Two", 3).Return("three").Times(8)
755
756	f, c := m.findExpectedCall("Two", 3)
757
758	if assert.Equal(t, 2, f) {
759		if assert.NotNil(t, c) {
760			assert.Equal(t, "Two", c.Method)
761			assert.Equal(t, 3, c.Arguments[0])
762			assert.Equal(t, "three", c.ReturnArguments[0])
763		}
764	}
765
766	c = m.On("Once", 1).Return("one").Once()
767	c.Repeatability = -1
768	f, c = m.findExpectedCall("Once", 1)
769	if assert.Equal(t, -1, f) {
770		if assert.NotNil(t, c) {
771			assert.Equal(t, "Once", c.Method)
772			assert.Equal(t, 1, c.Arguments[0])
773			assert.Equal(t, "one", c.ReturnArguments[0])
774		}
775	}
776}
777
778func Test_callString(t *testing.T) {
779
780	assert.Equal(t, `Method(int,bool,string)`, callString("Method", []interface{}{1, true, "something"}, false))
781	assert.Equal(t, `Method(<nil>)`, callString("Method", []interface{}{nil}, false))
782
783}
784
785func Test_Mock_Called(t *testing.T) {
786
787	var mockedService = new(TestExampleImplementation)
788
789	mockedService.On("Test_Mock_Called", 1, 2, 3).Return(5, "6", true)
790
791	returnArguments := mockedService.Called(1, 2, 3)
792
793	if assert.Equal(t, 1, len(mockedService.Calls)) {
794		assert.Equal(t, "Test_Mock_Called", mockedService.Calls[0].Method)
795		assert.Equal(t, 1, mockedService.Calls[0].Arguments[0])
796		assert.Equal(t, 2, mockedService.Calls[0].Arguments[1])
797		assert.Equal(t, 3, mockedService.Calls[0].Arguments[2])
798	}
799
800	if assert.Equal(t, 3, len(returnArguments)) {
801		assert.Equal(t, 5, returnArguments[0])
802		assert.Equal(t, "6", returnArguments[1])
803		assert.Equal(t, true, returnArguments[2])
804	}
805
806}
807
808func asyncCall(m *Mock, ch chan Arguments) {
809	ch <- m.Called(1, 2, 3)
810}
811
812func Test_Mock_Called_blocks(t *testing.T) {
813
814	var mockedService = new(TestExampleImplementation)
815
816	mockedService.Mock.On("asyncCall", 1, 2, 3).Return(5, "6", true).After(2 * time.Millisecond)
817
818	ch := make(chan Arguments)
819
820	go asyncCall(&mockedService.Mock, ch)
821
822	select {
823	case <-ch:
824		t.Fatal("should have waited")
825	case <-time.After(1 * time.Millisecond):
826	}
827
828	returnArguments := <-ch
829
830	if assert.Equal(t, 1, len(mockedService.Mock.Calls)) {
831		assert.Equal(t, "asyncCall", mockedService.Mock.Calls[0].Method)
832		assert.Equal(t, 1, mockedService.Mock.Calls[0].Arguments[0])
833		assert.Equal(t, 2, mockedService.Mock.Calls[0].Arguments[1])
834		assert.Equal(t, 3, mockedService.Mock.Calls[0].Arguments[2])
835	}
836
837	if assert.Equal(t, 3, len(returnArguments)) {
838		assert.Equal(t, 5, returnArguments[0])
839		assert.Equal(t, "6", returnArguments[1])
840		assert.Equal(t, true, returnArguments[2])
841	}
842
843}
844
845func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) {
846
847	var mockedService = new(TestExampleImplementation)
848
849	mockedService.
850		On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).
851		Return(5, "6", true).
852		Once()
853	mockedService.
854		On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).
855		Return(-1, "hi", false)
856
857	returnArguments1 := mockedService.Called(1, 2, 3)
858	returnArguments2 := mockedService.Called(1, 2, 3)
859
860	if assert.Equal(t, 2, len(mockedService.Calls)) {
861		assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[0].Method)
862		assert.Equal(t, 1, mockedService.Calls[0].Arguments[0])
863		assert.Equal(t, 2, mockedService.Calls[0].Arguments[1])
864		assert.Equal(t, 3, mockedService.Calls[0].Arguments[2])
865
866		assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[1].Method)
867		assert.Equal(t, 1, mockedService.Calls[1].Arguments[0])
868		assert.Equal(t, 2, mockedService.Calls[1].Arguments[1])
869		assert.Equal(t, 3, mockedService.Calls[1].Arguments[2])
870	}
871
872	if assert.Equal(t, 3, len(returnArguments1)) {
873		assert.Equal(t, 5, returnArguments1[0])
874		assert.Equal(t, "6", returnArguments1[1])
875		assert.Equal(t, true, returnArguments1[2])
876	}
877
878	if assert.Equal(t, 3, len(returnArguments2)) {
879		assert.Equal(t, -1, returnArguments2[0])
880		assert.Equal(t, "hi", returnArguments2[1])
881		assert.Equal(t, false, returnArguments2[2])
882	}
883
884}
885
886func Test_Mock_Called_For_SetTime_Expectation(t *testing.T) {
887
888	var mockedService = new(TestExampleImplementation)
889
890	mockedService.On("TheExampleMethod", 1, 2, 3).Return(5, "6", true).Times(4)
891
892	mockedService.TheExampleMethod(1, 2, 3)
893	mockedService.TheExampleMethod(1, 2, 3)
894	mockedService.TheExampleMethod(1, 2, 3)
895	mockedService.TheExampleMethod(1, 2, 3)
896	assert.Panics(t, func() {
897		mockedService.TheExampleMethod(1, 2, 3)
898	})
899
900}
901
902func Test_Mock_Called_Unexpected(t *testing.T) {
903
904	var mockedService = new(TestExampleImplementation)
905
906	// make sure it panics if no expectation was made
907	assert.Panics(t, func() {
908		mockedService.Called(1, 2, 3)
909	}, "Calling unexpected method should panic")
910
911}
912
913func Test_AssertExpectationsForObjects_Helper(t *testing.T) {
914
915	var mockedService1 = new(TestExampleImplementation)
916	var mockedService2 = new(TestExampleImplementation)
917	var mockedService3 = new(TestExampleImplementation)
918
919	mockedService1.On("Test_AssertExpectationsForObjects_Helper", 1).Return()
920	mockedService2.On("Test_AssertExpectationsForObjects_Helper", 2).Return()
921	mockedService3.On("Test_AssertExpectationsForObjects_Helper", 3).Return()
922
923	mockedService1.Called(1)
924	mockedService2.Called(2)
925	mockedService3.Called(3)
926
927	assert.True(t, AssertExpectationsForObjects(t, &mockedService1.Mock, &mockedService2.Mock, &mockedService3.Mock))
928	assert.True(t, AssertExpectationsForObjects(t, mockedService1, mockedService2, mockedService3))
929
930}
931
932func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) {
933
934	var mockedService1 = new(TestExampleImplementation)
935	var mockedService2 = new(TestExampleImplementation)
936	var mockedService3 = new(TestExampleImplementation)
937
938	mockedService1.On("Test_AssertExpectationsForObjects_Helper_Failed", 1).Return()
939	mockedService2.On("Test_AssertExpectationsForObjects_Helper_Failed", 2).Return()
940	mockedService3.On("Test_AssertExpectationsForObjects_Helper_Failed", 3).Return()
941
942	mockedService1.Called(1)
943	mockedService3.Called(3)
944
945	tt := new(testing.T)
946	assert.False(t, AssertExpectationsForObjects(tt, &mockedService1.Mock, &mockedService2.Mock, &mockedService3.Mock))
947	assert.False(t, AssertExpectationsForObjects(tt, mockedService1, mockedService2, mockedService3))
948
949}
950
951func Test_Mock_AssertExpectations(t *testing.T) {
952
953	var mockedService = new(TestExampleImplementation)
954
955	mockedService.On("Test_Mock_AssertExpectations", 1, 2, 3).Return(5, 6, 7)
956
957	tt := new(testing.T)
958	assert.False(t, mockedService.AssertExpectations(tt))
959
960	// make the call now
961	mockedService.Called(1, 2, 3)
962
963	// now assert expectations
964	assert.True(t, mockedService.AssertExpectations(tt))
965
966}
967
968func Test_Mock_AssertExpectations_Placeholder_NoArgs(t *testing.T) {
969
970	var mockedService = new(TestExampleImplementation)
971
972	mockedService.On("Test_Mock_AssertExpectations_Placeholder_NoArgs").Return(5, 6, 7).Once()
973	mockedService.On("Test_Mock_AssertExpectations_Placeholder_NoArgs").Return(7, 6, 5)
974
975	tt := new(testing.T)
976	assert.False(t, mockedService.AssertExpectations(tt))
977
978	// make the call now
979	mockedService.Called()
980
981	// now assert expectations
982	assert.True(t, mockedService.AssertExpectations(tt))
983
984}
985
986func Test_Mock_AssertExpectations_Placeholder(t *testing.T) {
987
988	var mockedService = new(TestExampleImplementation)
989
990	mockedService.On("Test_Mock_AssertExpectations_Placeholder", 1, 2, 3).Return(5, 6, 7).Once()
991	mockedService.On("Test_Mock_AssertExpectations_Placeholder", 3, 2, 1).Return(7, 6, 5)
992
993	tt := new(testing.T)
994	assert.False(t, mockedService.AssertExpectations(tt))
995
996	// make the call now
997	mockedService.Called(1, 2, 3)
998
999	// now assert expectations
1000	assert.False(t, mockedService.AssertExpectations(tt))
1001
1002	// make call to the second expectation
1003	mockedService.Called(3, 2, 1)
1004
1005	// now assert expectations again
1006	assert.True(t, mockedService.AssertExpectations(tt))
1007}
1008
1009func Test_Mock_AssertExpectations_With_Pointers(t *testing.T) {
1010
1011	var mockedService = new(TestExampleImplementation)
1012
1013	mockedService.On("Test_Mock_AssertExpectations_With_Pointers", &struct{ Foo int }{1}).Return(1)
1014	mockedService.On("Test_Mock_AssertExpectations_With_Pointers", &struct{ Foo int }{2}).Return(2)
1015
1016	tt := new(testing.T)
1017	assert.False(t, mockedService.AssertExpectations(tt))
1018
1019	s := struct{ Foo int }{1}
1020	// make the calls now
1021	mockedService.Called(&s)
1022	s.Foo = 2
1023	mockedService.Called(&s)
1024
1025	// now assert expectations
1026	assert.True(t, mockedService.AssertExpectations(tt))
1027
1028}
1029
1030func Test_Mock_AssertExpectationsCustomType(t *testing.T) {
1031
1032	var mockedService = new(TestExampleImplementation)
1033
1034	mockedService.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Once()
1035
1036	tt := new(testing.T)
1037	assert.False(t, mockedService.AssertExpectations(tt))
1038
1039	// make the call now
1040	mockedService.TheExampleMethod3(&ExampleType{})
1041
1042	// now assert expectations
1043	assert.True(t, mockedService.AssertExpectations(tt))
1044
1045}
1046
1047func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) {
1048
1049	var mockedService = new(TestExampleImplementation)
1050
1051	mockedService.On("Test_Mock_AssertExpectations_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Twice()
1052
1053	tt := new(testing.T)
1054	assert.False(t, mockedService.AssertExpectations(tt))
1055
1056	// make the call now
1057	mockedService.Called(1, 2, 3)
1058
1059	assert.False(t, mockedService.AssertExpectations(tt))
1060
1061	mockedService.Called(1, 2, 3)
1062
1063	// now assert expectations
1064	assert.True(t, mockedService.AssertExpectations(tt))
1065
1066}
1067
1068func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) {
1069
1070	var mockedService = new(TestExampleImplementation)
1071
1072	mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 1, 2, 3).Return(5, 6, 7)
1073	mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 4, 5, 6).Return(5, 6, 7)
1074
1075	args1 := mockedService.Called(1, 2, 3)
1076	assert.Equal(t, 5, args1.Int(0))
1077	assert.Equal(t, 6, args1.Int(1))
1078	assert.Equal(t, 7, args1.Int(2))
1079
1080	args2 := mockedService.Called(4, 5, 6)
1081	assert.Equal(t, 5, args2.Int(0))
1082	assert.Equal(t, 6, args2.Int(1))
1083	assert.Equal(t, 7, args2.Int(2))
1084
1085}
1086
1087func Test_Mock_AssertNumberOfCalls(t *testing.T) {
1088
1089	var mockedService = new(TestExampleImplementation)
1090
1091	mockedService.On("Test_Mock_AssertNumberOfCalls", 1, 2, 3).Return(5, 6, 7)
1092
1093	mockedService.Called(1, 2, 3)
1094	assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 1))
1095
1096	mockedService.Called(1, 2, 3)
1097	assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 2))
1098
1099}
1100
1101func Test_Mock_AssertCalled(t *testing.T) {
1102
1103	var mockedService = new(TestExampleImplementation)
1104
1105	mockedService.On("Test_Mock_AssertCalled", 1, 2, 3).Return(5, 6, 7)
1106
1107	mockedService.Called(1, 2, 3)
1108
1109	assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled", 1, 2, 3))
1110
1111}
1112
1113func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) {
1114
1115	var mockedService = new(TestExampleImplementation)
1116
1117	mockedService.
1118		On("Test_Mock_AssertCalled_WithAnythingOfTypeArgument", Anything, Anything, Anything).
1119		Return()
1120
1121	mockedService.Called(1, "two", []uint8("three"))
1122
1123	assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled_WithAnythingOfTypeArgument", AnythingOfType("int"), AnythingOfType("string"), AnythingOfType("[]uint8")))
1124
1125}
1126
1127func Test_Mock_AssertCalled_WithArguments(t *testing.T) {
1128
1129	var mockedService = new(TestExampleImplementation)
1130
1131	mockedService.On("Test_Mock_AssertCalled_WithArguments", 1, 2, 3).Return(5, 6, 7)
1132
1133	mockedService.Called(1, 2, 3)
1134
1135	tt := new(testing.T)
1136	assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 1, 2, 3))
1137	assert.False(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 2, 3, 4))
1138
1139}
1140
1141func Test_Mock_AssertCalled_WithArguments_With_Repeatability(t *testing.T) {
1142
1143	var mockedService = new(TestExampleImplementation)
1144
1145	mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Once()
1146	mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4).Return(5, 6, 7).Once()
1147
1148	mockedService.Called(1, 2, 3)
1149	mockedService.Called(2, 3, 4)
1150
1151	tt := new(testing.T)
1152	assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3))
1153	assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4))
1154	assert.False(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 3, 4, 5))
1155
1156}
1157
1158func Test_Mock_AssertNotCalled(t *testing.T) {
1159
1160	var mockedService = new(TestExampleImplementation)
1161
1162	mockedService.On("Test_Mock_AssertNotCalled", 1, 2, 3).Return(5, 6, 7)
1163
1164	mockedService.Called(1, 2, 3)
1165
1166	assert.True(t, mockedService.AssertNotCalled(t, "Test_Mock_NotCalled"))
1167
1168}
1169
1170func Test_Mock_IsMethodCallable(t *testing.T) {
1171	var mockedService = new(TestExampleImplementation)
1172
1173	arg := []Call{{Repeatability: 1}, {Repeatability: 2}}
1174	arg2 := []Call{{Repeatability: 1}, {Repeatability: 1}}
1175	arg3 := []Call{{Repeatability: 1}, {Repeatability: 1}}
1176
1177	mockedService.On("Test_Mock_IsMethodCallable", arg2).Return(true).Twice()
1178
1179	assert.False(t, mockedService.IsMethodCallable(t, "Test_Mock_IsMethodCallable", arg))
1180	assert.True(t, mockedService.IsMethodCallable(t, "Test_Mock_IsMethodCallable", arg2))
1181	assert.True(t, mockedService.IsMethodCallable(t, "Test_Mock_IsMethodCallable", arg3))
1182
1183	mockedService.MethodCalled("Test_Mock_IsMethodCallable", arg2)
1184	mockedService.MethodCalled("Test_Mock_IsMethodCallable", arg2)
1185
1186	assert.False(t, mockedService.IsMethodCallable(t, "Test_Mock_IsMethodCallable", arg2))
1187}
1188
1189func TestIsArgsEqual(t *testing.T) {
1190	var expected = Arguments{5, 3, 4, 6, 7, 2}
1191	var args = make([]interface{}, 5)
1192	for i := 1; i < len(expected); i++ {
1193		args[i-1] = expected[i]
1194	}
1195	args[2] = expected[1]
1196	assert.False(t, isArgsEqual(expected, args))
1197
1198	var arr = make([]interface{}, 6)
1199	for i := 0; i < len(expected); i++ {
1200		arr[i] = expected[i]
1201	}
1202	assert.True(t, isArgsEqual(expected, arr))
1203}
1204
1205func Test_Mock_AssertOptional(t *testing.T) {
1206	// Optional called
1207	var ms1 = new(TestExampleImplementation)
1208	ms1.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
1209	ms1.TheExampleMethod(1, 2, 3)
1210
1211	tt1 := new(testing.T)
1212	assert.Equal(t, true, ms1.AssertExpectations(tt1))
1213
1214	// Optional not called
1215	var ms2 = new(TestExampleImplementation)
1216	ms2.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
1217
1218	tt2 := new(testing.T)
1219	assert.Equal(t, true, ms2.AssertExpectations(tt2))
1220
1221	// Non-optional called
1222	var ms3 = new(TestExampleImplementation)
1223	ms3.On("TheExampleMethod", 1, 2, 3).Return(4, nil)
1224	ms3.TheExampleMethod(1, 2, 3)
1225
1226	tt3 := new(testing.T)
1227	assert.Equal(t, true, ms3.AssertExpectations(tt3))
1228}
1229
1230/*
1231	Arguments helper methods
1232*/
1233func Test_Arguments_Get(t *testing.T) {
1234
1235	var args = Arguments([]interface{}{"string", 123, true})
1236
1237	assert.Equal(t, "string", args.Get(0).(string))
1238	assert.Equal(t, 123, args.Get(1).(int))
1239	assert.Equal(t, true, args.Get(2).(bool))
1240
1241}
1242
1243func Test_Arguments_Is(t *testing.T) {
1244
1245	var args = Arguments([]interface{}{"string", 123, true})
1246
1247	assert.True(t, args.Is("string", 123, true))
1248	assert.False(t, args.Is("wrong", 456, false))
1249
1250}
1251
1252func Test_Arguments_Diff(t *testing.T) {
1253
1254	var args = Arguments([]interface{}{"Hello World", 123, true})
1255	var diff string
1256	var count int
1257	diff, count = args.Diff([]interface{}{"Hello World", 456, "false"})
1258
1259	assert.Equal(t, 2, count)
1260	assert.Contains(t, diff, `(int=456) != (int=123)`)
1261	assert.Contains(t, diff, `(string=false) != (bool=true)`)
1262
1263}
1264
1265func Test_Arguments_Diff_DifferentNumberOfArgs(t *testing.T) {
1266
1267	var args = Arguments([]interface{}{"string", 123, true})
1268	var diff string
1269	var count int
1270	diff, count = args.Diff([]interface{}{"string", 456, "false", "extra"})
1271
1272	assert.Equal(t, 3, count)
1273	assert.Contains(t, diff, `(string=extra) != (Missing)`)
1274
1275}
1276
1277func Test_Arguments_Diff_WithAnythingArgument(t *testing.T) {
1278
1279	var args = Arguments([]interface{}{"string", 123, true})
1280	var count int
1281	_, count = args.Diff([]interface{}{"string", Anything, true})
1282
1283	assert.Equal(t, 0, count)
1284
1285}
1286
1287func Test_Arguments_Diff_WithAnythingArgument_InActualToo(t *testing.T) {
1288
1289	var args = Arguments([]interface{}{"string", Anything, true})
1290	var count int
1291	_, count = args.Diff([]interface{}{"string", 123, true})
1292
1293	assert.Equal(t, 0, count)
1294
1295}
1296
1297func Test_Arguments_Diff_WithAnythingOfTypeArgument(t *testing.T) {
1298
1299	var args = Arguments([]interface{}{"string", AnythingOfType("int"), true})
1300	var count int
1301	_, count = args.Diff([]interface{}{"string", 123, true})
1302
1303	assert.Equal(t, 0, count)
1304
1305}
1306
1307func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) {
1308
1309	var args = Arguments([]interface{}{"string", AnythingOfType("string"), true})
1310	var count int
1311	var diff string
1312	diff, count = args.Diff([]interface{}{"string", 123, true})
1313
1314	assert.Equal(t, 1, count)
1315	assert.Contains(t, diff, `string != type int - (int=123)`)
1316
1317}
1318
1319func Test_Arguments_Diff_WithIsTypeArgument(t *testing.T) {
1320	var args = Arguments([]interface{}{"string", IsType(0), true})
1321	var count int
1322	_, count = args.Diff([]interface{}{"string", 123, true})
1323
1324	assert.Equal(t, 0, count)
1325}
1326
1327func Test_Arguments_Diff_WithIsTypeArgument_Failing(t *testing.T) {
1328	var args = Arguments([]interface{}{"string", IsType(""), true})
1329	var count int
1330	var diff string
1331	diff, count = args.Diff([]interface{}{"string", 123, true})
1332
1333	assert.Equal(t, 1, count)
1334	assert.Contains(t, diff, `string != type int - (int=123)`)
1335}
1336
1337func Test_Arguments_Diff_WithArgMatcher(t *testing.T) {
1338	matchFn := func(a int) bool {
1339		return a == 123
1340	}
1341	var args = Arguments([]interface{}{"string", MatchedBy(matchFn), true})
1342
1343	diff, count := args.Diff([]interface{}{"string", 124, true})
1344	assert.Equal(t, 1, count)
1345	assert.Contains(t, diff, `(int=124) not matched by func(int) bool`)
1346
1347	diff, count = args.Diff([]interface{}{"string", false, true})
1348	assert.Equal(t, 1, count)
1349	assert.Contains(t, diff, `(bool=false) not matched by func(int) bool`)
1350
1351	diff, count = args.Diff([]interface{}{"string", 123, false})
1352	assert.Equal(t, 1, count)
1353	assert.Contains(t, diff, `(int=123) matched by func(int) bool`)
1354
1355	diff, count = args.Diff([]interface{}{"string", 123, true})
1356	assert.Equal(t, 0, count)
1357	assert.Contains(t, diff, `No differences.`)
1358}
1359
1360func Test_Arguments_Assert(t *testing.T) {
1361
1362	var args = Arguments([]interface{}{"string", 123, true})
1363
1364	assert.True(t, args.Assert(t, "string", 123, true))
1365
1366}
1367
1368func Test_Arguments_String_Representation(t *testing.T) {
1369
1370	var args = Arguments([]interface{}{"string", 123, true})
1371	assert.Equal(t, `string,int,bool`, args.String())
1372
1373}
1374
1375func Test_Arguments_String(t *testing.T) {
1376
1377	var args = Arguments([]interface{}{"string", 123, true})
1378	assert.Equal(t, "string", args.String(0))
1379
1380}
1381
1382func Test_Arguments_Error(t *testing.T) {
1383
1384	var err = errors.New("An Error")
1385	var args = Arguments([]interface{}{"string", 123, true, err})
1386	assert.Equal(t, err, args.Error(3))
1387
1388}
1389
1390func Test_Arguments_Error_Nil(t *testing.T) {
1391
1392	var args = Arguments([]interface{}{"string", 123, true, nil})
1393	assert.Equal(t, nil, args.Error(3))
1394
1395}
1396
1397func Test_Arguments_Int(t *testing.T) {
1398
1399	var args = Arguments([]interface{}{"string", 123, true})
1400	assert.Equal(t, 123, args.Int(1))
1401
1402}
1403
1404func Test_Arguments_Bool(t *testing.T) {
1405
1406	var args = Arguments([]interface{}{"string", 123, true})
1407	assert.Equal(t, true, args.Bool(2))
1408
1409}
1410
1411func Test_WaitUntil_Parallel(t *testing.T) {
1412
1413	// make a test impl object
1414	var mockedService = new(TestExampleImplementation)
1415
1416	ch1 := make(chan time.Time)
1417	ch2 := make(chan time.Time)
1418
1419	mockedService.Mock.On("TheExampleMethod2", true).Return().WaitUntil(ch2).Run(func(args Arguments) {
1420		ch1 <- time.Now()
1421	})
1422
1423	mockedService.Mock.On("TheExampleMethod2", false).Return().WaitUntil(ch1)
1424
1425	// Lock both goroutines on the .WaitUntil method
1426	go func() {
1427		mockedService.TheExampleMethod2(false)
1428	}()
1429	go func() {
1430		mockedService.TheExampleMethod2(true)
1431	}()
1432
1433	// Allow the first call to execute, so the second one executes afterwards
1434	ch2 <- time.Now()
1435}
1436
1437func Test_MockMethodCalled(t *testing.T) {
1438	m := new(Mock)
1439	m.On("foo", "hello").Return("world")
1440
1441	retArgs := m.MethodCalled("foo", "hello")
1442	require.True(t, len(retArgs) == 1)
1443	require.Equal(t, "world", retArgs[0])
1444	m.AssertExpectations(t)
1445}
1446
1447func Test_MockMethodCalled_Panic(t *testing.T) {
1448	m := new(Mock)
1449	m.On("foo", "hello").Panic("world panics")
1450
1451	require.PanicsWithValue(t, "world panics", func() { m.MethodCalled("foo", "hello") })
1452	m.AssertExpectations(t)
1453}
1454
1455// Test to validate fix for racy concurrent call access in MethodCalled()
1456func Test_MockReturnAndCalledConcurrent(t *testing.T) {
1457	iterations := 1000
1458	m := &Mock{}
1459	call := m.On("ConcurrencyTestMethod")
1460
1461	wg := sync.WaitGroup{}
1462	wg.Add(2)
1463
1464	go func() {
1465		for i := 0; i < iterations; i++ {
1466			call.Return(10)
1467		}
1468		wg.Done()
1469	}()
1470	go func() {
1471		for i := 0; i < iterations; i++ {
1472			ConcurrencyTestMethod(m)
1473		}
1474		wg.Done()
1475	}()
1476	wg.Wait()
1477}
1478
1479type timer struct{ Mock }
1480
1481func (s *timer) GetTime(i int) string {
1482	return s.Called(i).Get(0).(string)
1483}
1484
1485type tCustomLogger struct {
1486	*testing.T
1487	logs []string
1488	errs []string
1489}
1490
1491func (tc *tCustomLogger) Logf(format string, args ...interface{}) {
1492	tc.T.Logf(format, args...)
1493	tc.logs = append(tc.logs, fmt.Sprintf(format, args...))
1494}
1495
1496func (tc *tCustomLogger) Errorf(format string, args ...interface{}) {
1497	tc.errs = append(tc.errs, fmt.Sprintf(format, args...))
1498}
1499
1500func (tc *tCustomLogger) FailNow() {}
1501
1502func TestLoggingAssertExpectations(t *testing.T) {
1503	m := new(timer)
1504	m.On("GetTime", 0).Return("")
1505	tcl := &tCustomLogger{t, []string{}, []string{}}
1506
1507	AssertExpectationsForObjects(tcl, m, new(TestExampleImplementation))
1508
1509	require.Equal(t, 1, len(tcl.errs))
1510	assert.Regexp(t, regexp.MustCompile("(?s)FAIL: 0 out of 1 expectation\\(s\\) were met.*The code you are testing needs to make 1 more call\\(s\\).*"), tcl.errs[0])
1511	require.Equal(t, 2, len(tcl.logs))
1512	assert.Regexp(t, regexp.MustCompile("(?s)FAIL:\tGetTime\\(int\\).*"), tcl.logs[0])
1513	require.Equal(t, "Expectations didn't match for Mock: *mock.timer", tcl.logs[1])
1514}
1515
1516func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
1517	waitDuration := 1
1518	total, waitMs := 5, time.Millisecond*time.Duration(waitDuration)
1519	aTimer := new(timer)
1520	for i := 0; i < total; i++ {
1521		aTimer.On("GetTime", i).After(waitMs).Return(fmt.Sprintf("Time%d", i)).Once()
1522	}
1523	time.Sleep(waitMs)
1524	start := time.Now()
1525	var results []string
1526
1527	for i := 0; i < total; i++ {
1528		results = append(results, aTimer.GetTime(i))
1529	}
1530
1531	end := time.Now()
1532	elapsedTime := end.Sub(start)
1533	assert.True(t, elapsedTime > waitMs, fmt.Sprintf("Total elapsed time:%v should be atleast greater than %v", elapsedTime, waitMs))
1534	assert.Equal(t, total, len(results))
1535	for i := range results {
1536		assert.Equal(t, fmt.Sprintf("Time%d", i), results[i], "Return value of method should be same")
1537	}
1538}
1539
1540func TestArgumentMatcherToPrintMismatch(t *testing.T) {
1541	defer func() {
1542		if r := recover(); r != nil {
1543			matchingExp := regexp.MustCompile(
1544				`\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool`)
1545			assert.Regexp(t, matchingExp, r)
1546		}
1547	}()
1548
1549	m := new(timer)
1550	m.On("GetTime", MatchedBy(func(i int) bool { return false })).Return("SomeTime").Once()
1551
1552	res := m.GetTime(1)
1553	require.Equal(t, "SomeTime", res)
1554	m.AssertExpectations(t)
1555}
1556
1557func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) {
1558	defer func() {
1559		if r := recover(); r != nil {
1560			matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod(int,int,int)`, `0: 1\s+1: 1\s+2: 2`, `0: 1\s+1: 1\s+2: 1`, `Diff: 0: PASS:  \(int=1\) == \(int=1\)\s+1: PASS:  \(int=1\) == \(int=1\)\s+2: FAIL:  \(int=2\) != \(int=1\)`))
1561			assert.Regexp(t, matchingExp, r)
1562		}
1563	}()
1564
1565	m := new(TestExampleImplementation)
1566	m.On("TheExampleMethod", 1, 1, 1).Return(1, nil).Once()
1567	m.On("TheExampleMethod", 2, 2, 2).Return(2, nil).Once()
1568
1569	m.TheExampleMethod(1, 1, 2)
1570}
1571
1572func TestClosestCallFavorsFirstMock(t *testing.T) {
1573	defer func() {
1574		if r := recover(); r != nil {
1575			diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -2,4 \+2,4 @@\s+\(bool\) true,\s+- \(bool\) true,\s+- \(bool\) true\s+\+ \(bool\) false,\s+\+ \(bool\) false\s+}\s+`
1576			matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, false, false}`, `0: \[\]bool{true, true, true}`, diffRegExp))
1577			assert.Regexp(t, matchingExp, r)
1578		}
1579	}()
1580
1581	m := new(TestExampleImplementation)
1582	m.On("TheExampleMethod7", []bool{true, true, true}).Return(nil).Once()
1583	m.On("TheExampleMethod7", []bool{false, false, false}).Return(nil).Once()
1584
1585	m.TheExampleMethod7([]bool{true, false, false})
1586}
1587
1588func TestClosestCallUsesRepeatabilityToFindClosest(t *testing.T) {
1589	defer func() {
1590		if r := recover(); r != nil {
1591			diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -1,4 \+1,4 @@\s+\(\[\]bool\) \(len=3\) {\s+- \(bool\) false,\s+- \(bool\) false,\s+\+ \(bool\) true,\s+\+ \(bool\) true,\s+\(bool\) false\s+`
1592			matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, true, false}`, `0: \[\]bool{false, false, false}`, diffRegExp))
1593			assert.Regexp(t, matchingExp, r)
1594		}
1595	}()
1596
1597	m := new(TestExampleImplementation)
1598	m.On("TheExampleMethod7", []bool{true, true, true}).Return(nil).Once()
1599	m.On("TheExampleMethod7", []bool{false, false, false}).Return(nil).Once()
1600
1601	m.TheExampleMethod7([]bool{true, true, true})
1602
1603	// Since the first mocked call has already been used, it now has no repeatability,
1604	// thus the second mock should be shown as the closest match
1605	m.TheExampleMethod7([]bool{true, true, false})
1606}
1607
1608func TestClosestCallMismatchedArgumentValueInformation(t *testing.T) {
1609	defer func() {
1610		if r := recover(); r != nil {
1611			matchingExp := regexp.MustCompile(unexpectedCallRegex(`GetTime(int)`, "0: 1", "0: 999", `Diff: 0: FAIL:  \(int=1\) != \(int=999\)`))
1612			assert.Regexp(t, matchingExp, r)
1613		}
1614	}()
1615
1616	m := new(timer)
1617	m.On("GetTime", 999).Return("SomeTime").Once()
1618
1619	_ = m.GetTime(1)
1620}
1621
1622func Test_isBetterMatchThanReturnsFalseIfCandidateCallIsNil(t *testing.T) {
1623	assert.False(t, matchCandidate{}.isBetterMatchThan(matchCandidate{}))
1624}
1625
1626func Test_isBetterMatchThanReturnsTrueIfOtherCandidateCallIsNil(t *testing.T) {
1627	assert.True(t, matchCandidate{call: &Call{}}.isBetterMatchThan(matchCandidate{}))
1628}
1629
1630func Test_isBetterMatchThanReturnsFalseIfDiffCountIsGreaterThanOther(t *testing.T) {
1631	assert.False(t, matchCandidate{call: &Call{}, diffCount: 2}.isBetterMatchThan(matchCandidate{call: &Call{}, diffCount: 1}))
1632}
1633
1634func Test_isBetterMatchThanReturnsTrueIfDiffCountIsLessThanOther(t *testing.T) {
1635	assert.True(t, matchCandidate{call: &Call{}, diffCount: 1}.isBetterMatchThan(matchCandidate{call: &Call{}, diffCount: 2}))
1636}
1637
1638func Test_isBetterMatchThanReturnsTrueIfRepeatabilityIsGreaterThanOther(t *testing.T) {
1639	assert.True(t, matchCandidate{call: &Call{Repeatability: 1}, diffCount: 1}.isBetterMatchThan(matchCandidate{call: &Call{Repeatability: -1}, diffCount: 1}))
1640}
1641
1642func Test_isBetterMatchThanReturnsFalseIfRepeatabilityIsLessThanOrEqualToOther(t *testing.T) {
1643	assert.False(t, matchCandidate{call: &Call{Repeatability: 1}, diffCount: 1}.isBetterMatchThan(matchCandidate{call: &Call{Repeatability: 1}, diffCount: 1}))
1644}
1645
1646func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
1647	rMethod := regexp.QuoteMeta(method)
1648	return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+%s`,
1649		rMethod, calledArg, rMethod, expectedArg, diff)
1650}
1651
1652//go:noinline
1653func ConcurrencyTestMethod(m *Mock) {
1654	m.Called()
1655}
1656