From 5c94bfc599944a772fc5f86afa449d83d3413be6 Mon Sep 17 00:00:00 2001 From: sleygin Date: Tue, 4 Jun 2024 01:59:27 +0300 Subject: [PATCH] FailNow removed from template + tests fixed --- Makefile | 1 + template.go | 3 +- tests/actor_mock.go | 17 +- tests/actor_mock_test.go | 9 + tests/context_accepter_mock.go | 49 +++++- tests/context_accepter_mock_test.go | 6 +- tests/formatter_mock.go | 17 +- tests/formatter_mock_test.go | 5 - tests/formatter_with_custom_name_mock.go | 157 +++++++++++++++--- tests/formatter_with_custom_name_mock_test.go | 51 +++++- tests/generic_complex_union.go | 17 +- tests/generic_in.go | 17 +- tests/generic_inline_union.go | 17 +- tests/generic_inline_with_many_options.go | 17 +- tests/generic_inout.go | 17 +- ...eric_multiple_args_with_different_types.go | 17 +- tests/generic_out.go | 17 +- tests/generic_simple_union.go | 17 +- tests/generic_specific.go | 17 +- tests/package_name_specified_test.go | 97 ++++++++++- tests/tester_mock_test.go | 97 ++++++++++- 21 files changed, 606 insertions(+), 56 deletions(-) diff --git a/Makefile b/Makefile index 66eaee3..132bd40 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ all: install test lint generate: go run ./cmd/minimock/minimock.go -i github.com/gojuno/minimock/v3.Tester -o ./tests go run ./cmd/minimock/minimock.go -i ./tests.Formatter -o ./tests/formatter_mock.go + go run ./cmd/minimock/minimock.go -i ./tests.Formatter -o ./tests/formatter_with_custom_name_mock.go -n CustomFormatterNameMock go run ./cmd/minimock/minimock.go -i ./tests.genericInout -o ./tests/generic_inout.go go run ./cmd/minimock/minimock.go -i ./tests.genericOut -o ./tests/generic_out.go go run ./cmd/minimock/minimock.go -i ./tests.genericIn -o ./tests/generic_in.go diff --git a/template.go b/template.go index 261c894..375700a 100644 --- a/template.go +++ b/template.go @@ -104,7 +104,7 @@ const ( // Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning // the test will fail minimock's automatic final call check if the mocked method was not called at least once. // Optional() makes method check to work in '0 or more' mode. - // It is NOT RECOMMENDED to use this option by default unless you really need it, as it helps to + // It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to // catch the problems when the expected method call is totally skipped during test run. func ({{$m}} *m{{$mock}}{{$method.Name}}{{(paramsRef)}}) Optional() *m{{$mock}}{{$method.Name}}{{(paramsRef)}} { {{$m}}.optional = true @@ -386,7 +386,6 @@ const ( {{- range $method := $.Interface.Methods }} m.Minimock{{$method.Name}}Inspect() {{ end -}} - m.t.FailNow() } }) } diff --git a/tests/actor_mock.go b/tests/actor_mock.go index a88b2c0..9994373 100644 --- a/tests/actor_mock.go +++ b/tests/actor_mock.go @@ -41,6 +41,7 @@ func NewActorMock(t minimock.Tester) *ActorMock { } type mActorMockAction struct { + optional bool mock *ActorMock defaultExpectation *ActorMockActionExpectation expectations []*ActorMockActionExpectation @@ -78,6 +79,16 @@ type ActorMockActionResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmAction *mActorMockAction) Optional() *mActorMockAction { + mmAction.optional = true + return mmAction +} + // Expect sets up expected params for actor.Action func (mmAction *mActorMockAction) Expect(firstParam string, secondParam int) *mActorMockAction { if mmAction.mock.funcAction != nil { @@ -308,6 +319,11 @@ func (mmAction *mActorMockAction) Calls() []*ActorMockActionParams { // MinimockActionDone returns true if the count of the Action invocations corresponds // the number of defined expectations func (m *ActorMock) MinimockActionDone() bool { + if m.ActionMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ActionMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -350,7 +366,6 @@ func (m *ActorMock) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockActionInspect() - m.t.FailNow() } }) } diff --git a/tests/actor_mock_test.go b/tests/actor_mock_test.go index 3311817..1f0a0ea 100644 --- a/tests/actor_mock_test.go +++ b/tests/actor_mock_test.go @@ -83,3 +83,12 @@ func TestActorMock_FailedToUseExpectParamsAfterSet(t *testing.T) { return }).ActionMock.ExpectFirstParamParam1("abc").Return(1, nil) } + +func TestActorMock_Optional(t *testing.T) { + tester := NewTesterMock(t) + tester.CleanupMock.Return() + + mock := NewActorMock(tester).ActionMock.Optional().Return(1, nil) + + mock.MinimockFinish() +} diff --git a/tests/context_accepter_mock.go b/tests/context_accepter_mock.go index 89d5ba8..b1322f9 100644 --- a/tests/context_accepter_mock.go +++ b/tests/context_accepter_mock.go @@ -60,6 +60,7 @@ func NewContextAccepterMock(t minimock.Tester) *ContextAccepterMock { } type mContextAccepterMockAcceptContext struct { + optional bool mock *ContextAccepterMock defaultExpectation *ContextAccepterMockAcceptContextExpectation expectations []*ContextAccepterMockAcceptContextExpectation @@ -89,6 +90,16 @@ type ContextAccepterMockAcceptContextParamPtrs struct { ctx *context.Context } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmAcceptContext *mContextAccepterMockAcceptContext) Optional() *mContextAccepterMockAcceptContext { + mmAcceptContext.optional = true + return mmAcceptContext +} + // Expect sets up expected params for contextAccepter.AcceptContext func (mmAcceptContext *mContextAccepterMockAcceptContext) Expect(ctx context.Context) *mContextAccepterMockAcceptContext { if mmAcceptContext.mock.funcAcceptContext != nil { @@ -270,6 +281,11 @@ func (mmAcceptContext *mContextAccepterMockAcceptContext) Calls() []*ContextAcce // MinimockAcceptContextDone returns true if the count of the AcceptContext invocations corresponds // the number of defined expectations func (m *ContextAccepterMock) MinimockAcceptContextDone() bool { + if m.AcceptContextMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.AcceptContextMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -308,6 +324,7 @@ func (m *ContextAccepterMock) MinimockAcceptContextInspect() { } type mContextAccepterMockAcceptContextWithOtherArgs struct { + optional bool mock *ContextAccepterMock defaultExpectation *ContextAccepterMockAcceptContextWithOtherArgsExpectation expectations []*ContextAccepterMockAcceptContextWithOtherArgsExpectation @@ -345,6 +362,16 @@ type ContextAccepterMockAcceptContextWithOtherArgsResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmAcceptContextWithOtherArgs *mContextAccepterMockAcceptContextWithOtherArgs) Optional() *mContextAccepterMockAcceptContextWithOtherArgs { + mmAcceptContextWithOtherArgs.optional = true + return mmAcceptContextWithOtherArgs +} + // Expect sets up expected params for contextAccepter.AcceptContextWithOtherArgs func (mmAcceptContextWithOtherArgs *mContextAccepterMockAcceptContextWithOtherArgs) Expect(ctx context.Context, i1 int) *mContextAccepterMockAcceptContextWithOtherArgs { if mmAcceptContextWithOtherArgs.mock.funcAcceptContextWithOtherArgs != nil { @@ -575,6 +602,11 @@ func (mmAcceptContextWithOtherArgs *mContextAccepterMockAcceptContextWithOtherAr // MinimockAcceptContextWithOtherArgsDone returns true if the count of the AcceptContextWithOtherArgs invocations corresponds // the number of defined expectations func (m *ContextAccepterMock) MinimockAcceptContextWithOtherArgsDone() bool { + if m.AcceptContextWithOtherArgsMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.AcceptContextWithOtherArgsMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -613,6 +645,7 @@ func (m *ContextAccepterMock) MinimockAcceptContextWithOtherArgsInspect() { } type mContextAccepterMockAcceptContextWithStructArgs struct { + optional bool mock *ContextAccepterMock defaultExpectation *ContextAccepterMockAcceptContextWithStructArgsExpectation expectations []*ContextAccepterMockAcceptContextWithStructArgsExpectation @@ -650,6 +683,16 @@ type ContextAccepterMockAcceptContextWithStructArgsResults struct { err error } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmAcceptContextWithStructArgs *mContextAccepterMockAcceptContextWithStructArgs) Optional() *mContextAccepterMockAcceptContextWithStructArgs { + mmAcceptContextWithStructArgs.optional = true + return mmAcceptContextWithStructArgs +} + // Expect sets up expected params for contextAccepter.AcceptContextWithStructArgs func (mmAcceptContextWithStructArgs *mContextAccepterMockAcceptContextWithStructArgs) Expect(ctx context.Context, s1 structArg) *mContextAccepterMockAcceptContextWithStructArgs { if mmAcceptContextWithStructArgs.mock.funcAcceptContextWithStructArgs != nil { @@ -880,6 +923,11 @@ func (mmAcceptContextWithStructArgs *mContextAccepterMockAcceptContextWithStruct // MinimockAcceptContextWithStructArgsDone returns true if the count of the AcceptContextWithStructArgs invocations corresponds // the number of defined expectations func (m *ContextAccepterMock) MinimockAcceptContextWithStructArgsDone() bool { + if m.AcceptContextWithStructArgsMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.AcceptContextWithStructArgsMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -926,7 +974,6 @@ func (m *ContextAccepterMock) MinimockFinish() { m.MinimockAcceptContextWithOtherArgsInspect() m.MinimockAcceptContextWithStructArgsInspect() - m.t.FailNow() } }) } diff --git a/tests/context_accepter_mock_test.go b/tests/context_accepter_mock_test.go index c733245..eca9e46 100644 --- a/tests/context_accepter_mock_test.go +++ b/tests/context_accepter_mock_test.go @@ -139,8 +139,7 @@ func TestContextAccepterMock_TimesFailure(t *testing.T) { tester := NewTesterMock(t) tester.CleanupMock.Return(). ErrorfMock.Expect("Expected %d calls to ContextAccepterMock.AcceptContextWithStructArgs but found %d calls", uint64(1), uint64(2)). - Return(). - FailNowMock.Return() + Return() // Expected 1 calls to ContextAccepterMock.AcceptContextWithStructArgs but found 2 calls mock := NewContextAccepterMock(tester). @@ -183,8 +182,7 @@ func TestContextAccepterMock_ExpectedCall(t *testing.T) { tester := NewTesterMock(t) tester.CleanupMock.Times(1).Return(). ErrorMock.Expect("Expected call to ContextAccepterMock.AcceptContext").Times(1). - Return(). - FailNowMock.Times(1).Return() + Return() mock := NewContextAccepterMock(tester).AcceptContextMock.Return() diff --git a/tests/formatter_mock.go b/tests/formatter_mock.go index 6c73363..72ba2fc 100644 --- a/tests/formatter_mock.go +++ b/tests/formatter_mock.go @@ -41,6 +41,7 @@ func NewFormatterMock(t minimock.Tester) *FormatterMock { } type mFormatterMockFormat struct { + optional bool mock *FormatterMock defaultExpectation *FormatterMockFormatExpectation expectations []*FormatterMockFormatExpectation @@ -77,6 +78,16 @@ type FormatterMockFormatResults struct { s2 string } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFormat *mFormatterMockFormat) Optional() *mFormatterMockFormat { + mmFormat.optional = true + return mmFormat +} + // Expect sets up expected params for Formatter.Format func (mmFormat *mFormatterMockFormat) Expect(s1 string, p1 ...interface{}) *mFormatterMockFormat { if mmFormat.mock.funcFormat != nil { @@ -307,6 +318,11 @@ func (mmFormat *mFormatterMockFormat) Calls() []*FormatterMockFormatParams { // MinimockFormatDone returns true if the count of the Format invocations corresponds // the number of defined expectations func (m *FormatterMock) MinimockFormatDone() bool { + if m.FormatMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FormatMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -349,7 +365,6 @@ func (m *FormatterMock) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockFormatInspect() - m.t.FailNow() } }) } diff --git a/tests/formatter_mock_test.go b/tests/formatter_mock_test.go index 1a5fac1..71e0022 100644 --- a/tests/formatter_mock_test.go +++ b/tests/formatter_mock_test.go @@ -26,7 +26,6 @@ func TestFormatterMock_CleanupIsCalled(t *testing.T) { tester := NewTesterMock(t) tester.CleanupMock.Set(t.Cleanup) tester.ErrorMock.Expect("Expected call to FormatterMock.Format").Return() - tester.FailNowMock.Return() NewFormatterMock(tester).FormatMock.Return("") } @@ -154,7 +153,6 @@ func TestFormatterMock_ReturnWithoutExpectForFixedArgsMethod(t *testing.T) { tester := NewTesterMock(t).CleanupMock.Return() tester.ErrorMock.Expect("Expected call to FormatterMock.Format") - tester.FailNowMock.Expect() formatterMock := NewFormatterMock(tester) formatterMock.FormatMock.Return("") @@ -232,7 +230,6 @@ func TestFormatterMock_MinimockFinish(t *testing.T) { tester := NewTesterMock(t).CleanupMock.Return() tester.ErrorMock.Expect("Expected call to FormatterMock.Format").Return() - tester.FailNowMock.Expect().Return() formatterMock := NewFormatterMock(tester) formatterMock.FormatMock.Set(func(string, ...interface{}) string { return "" }) @@ -246,7 +243,6 @@ func TestFormatterMock_MinimockFinish_WithNoMetExpectations(t *testing.T) { tester.ErrorfMock.Set(func(m string, args ...interface{}) { assert.Equal(t, m, "Expected call to FormatterMock.Format with params: %#v") }) - tester.FailNowMock.Expect().Return() formatterMock := NewFormatterMock(tester) formatterMock.FormatMock.Expect("a").Return("a") @@ -259,7 +255,6 @@ func TestFormatterMock_MinimockWait(t *testing.T) { tester := NewTesterMock(t).CleanupMock.Return() tester.ErrorMock.Expect("Expected call to FormatterMock.Format").Return() - tester.FailNowMock.Expect().Return() formatterMock := NewFormatterMock(tester) formatterMock.FormatMock.Set(func(string, ...interface{}) string { return "" }) diff --git a/tests/formatter_with_custom_name_mock.go b/tests/formatter_with_custom_name_mock.go index bc6bc60..9f439db 100644 --- a/tests/formatter_with_custom_name_mock.go +++ b/tests/formatter_with_custom_name_mock.go @@ -1,8 +1,8 @@ -package tests - // Code generated by http://github.com/gojuno/minimock (dev). DO NOT EDIT. -//go:generate minimock -i github.com/gojuno/minimock/v3/tests.Formatter -o formatter_with_custom_name_mock.go -n CustomFormatterNameMock +package tests + +//go:generate minimock -i github.com/gojuno/minimock/v3/tests.Formatter -o formatter_with_custom_name_mock.go -n CustomFormatterNameMock -p tests import ( "sync" @@ -14,7 +14,8 @@ import ( // CustomFormatterNameMock implements Formatter type CustomFormatterNameMock struct { - t minimock.Tester + t minimock.Tester + finishOnce sync.Once funcFormat func(s1 string, p1 ...interface{}) (s2 string) inspectFuncFormat func(s1 string, p1 ...interface{}) @@ -26,6 +27,7 @@ type CustomFormatterNameMock struct { // NewCustomFormatterNameMock returns a mock for Formatter func NewCustomFormatterNameMock(t minimock.Tester) *CustomFormatterNameMock { m := &CustomFormatterNameMock{t: t} + if controller, ok := t.(minimock.MockController); ok { controller.RegisterMocker(m) } @@ -33,24 +35,30 @@ func NewCustomFormatterNameMock(t minimock.Tester) *CustomFormatterNameMock { m.FormatMock = mCustomFormatterNameMockFormat{mock: m} m.FormatMock.callArgs = []*CustomFormatterNameMockFormatParams{} + t.Cleanup(m.MinimockFinish) + return m } type mCustomFormatterNameMockFormat struct { + optional bool mock *CustomFormatterNameMock defaultExpectation *CustomFormatterNameMockFormatExpectation expectations []*CustomFormatterNameMockFormatExpectation callArgs []*CustomFormatterNameMockFormatParams mutex sync.RWMutex + + expectedInvocations uint64 } // CustomFormatterNameMockFormatExpectation specifies expectation struct of the Formatter.Format type CustomFormatterNameMockFormatExpectation struct { - mock *CustomFormatterNameMock - params *CustomFormatterNameMockFormatParams - results *CustomFormatterNameMockFormatResults - Counter uint64 + mock *CustomFormatterNameMock + params *CustomFormatterNameMockFormatParams + paramPtrs *CustomFormatterNameMockFormatParamPtrs + results *CustomFormatterNameMockFormatResults + Counter uint64 } // CustomFormatterNameMockFormatParams contains parameters of the Formatter.Format @@ -59,11 +67,27 @@ type CustomFormatterNameMockFormatParams struct { p1 []interface{} } +// CustomFormatterNameMockFormatParamPtrs contains pointers to parameters of the Formatter.Format +type CustomFormatterNameMockFormatParamPtrs struct { + s1 *string + p1 *[]interface{} +} + // CustomFormatterNameMockFormatResults contains results of the Formatter.Format type CustomFormatterNameMockFormatResults struct { s2 string } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFormat *mCustomFormatterNameMockFormat) Optional() *mCustomFormatterNameMockFormat { + mmFormat.optional = true + return mmFormat +} + // Expect sets up expected params for Formatter.Format func (mmFormat *mCustomFormatterNameMockFormat) Expect(s1 string, p1 ...interface{}) *mCustomFormatterNameMockFormat { if mmFormat.mock.funcFormat != nil { @@ -74,6 +98,10 @@ func (mmFormat *mCustomFormatterNameMockFormat) Expect(s1 string, p1 ...interfac mmFormat.defaultExpectation = &CustomFormatterNameMockFormatExpectation{} } + if mmFormat.defaultExpectation.paramPtrs != nil { + mmFormat.mock.t.Fatalf("CustomFormatterNameMock.Format mock is already set by ExpectParams functions") + } + mmFormat.defaultExpectation.params = &CustomFormatterNameMockFormatParams{s1, p1} for _, e := range mmFormat.expectations { if minimock.Equal(e.params, mmFormat.defaultExpectation.params) { @@ -84,6 +112,50 @@ func (mmFormat *mCustomFormatterNameMockFormat) Expect(s1 string, p1 ...interfac return mmFormat } +// ExpectS1Param1 sets up expected param s1 for Formatter.Format +func (mmFormat *mCustomFormatterNameMockFormat) ExpectS1Param1(s1 string) *mCustomFormatterNameMockFormat { + if mmFormat.mock.funcFormat != nil { + mmFormat.mock.t.Fatalf("CustomFormatterNameMock.Format mock is already set by Set") + } + + if mmFormat.defaultExpectation == nil { + mmFormat.defaultExpectation = &CustomFormatterNameMockFormatExpectation{} + } + + if mmFormat.defaultExpectation.params != nil { + mmFormat.mock.t.Fatalf("CustomFormatterNameMock.Format mock is already set by Expect") + } + + if mmFormat.defaultExpectation.paramPtrs == nil { + mmFormat.defaultExpectation.paramPtrs = &CustomFormatterNameMockFormatParamPtrs{} + } + mmFormat.defaultExpectation.paramPtrs.s1 = &s1 + + return mmFormat +} + +// ExpectP1Param2 sets up expected param p1 for Formatter.Format +func (mmFormat *mCustomFormatterNameMockFormat) ExpectP1Param2(p1 ...interface{}) *mCustomFormatterNameMockFormat { + if mmFormat.mock.funcFormat != nil { + mmFormat.mock.t.Fatalf("CustomFormatterNameMock.Format mock is already set by Set") + } + + if mmFormat.defaultExpectation == nil { + mmFormat.defaultExpectation = &CustomFormatterNameMockFormatExpectation{} + } + + if mmFormat.defaultExpectation.params != nil { + mmFormat.mock.t.Fatalf("CustomFormatterNameMock.Format mock is already set by Expect") + } + + if mmFormat.defaultExpectation.paramPtrs == nil { + mmFormat.defaultExpectation.paramPtrs = &CustomFormatterNameMockFormatParamPtrs{} + } + mmFormat.defaultExpectation.paramPtrs.p1 = &p1 + + return mmFormat +} + // Inspect accepts an inspector function that has same arguments as the Formatter.Format func (mmFormat *mCustomFormatterNameMockFormat) Inspect(f func(s1 string, p1 ...interface{})) *mCustomFormatterNameMockFormat { if mmFormat.mock.inspectFuncFormat != nil { @@ -143,6 +215,26 @@ func (e *CustomFormatterNameMockFormatExpectation) Then(s2 string) *CustomFormat return e.mock } +// Times sets number of times Formatter.Format should be invoked +func (mmFormat *mCustomFormatterNameMockFormat) Times(n uint64) *mCustomFormatterNameMockFormat { + if n == 0 { + mmFormat.mock.t.Fatalf("Times of CustomFormatterNameMock.Format mock can not be zero") + } + mm_atomic.StoreUint64(&mmFormat.expectedInvocations, n) + return mmFormat +} + +func (mmFormat *mCustomFormatterNameMockFormat) invocationsDone() bool { + if len(mmFormat.expectations) == 0 && mmFormat.defaultExpectation == nil && mmFormat.mock.funcFormat == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmFormat.mock.afterFormatCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmFormat.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + // Format implements Formatter func (mmFormat *CustomFormatterNameMock) Format(s1 string, p1 ...interface{}) (s2 string) { mm_atomic.AddUint64(&mmFormat.beforeFormatCounter, 1) @@ -169,8 +261,21 @@ func (mmFormat *CustomFormatterNameMock) Format(s1 string, p1 ...interface{}) (s if mmFormat.FormatMock.defaultExpectation != nil { mm_atomic.AddUint64(&mmFormat.FormatMock.defaultExpectation.Counter, 1) mm_want := mmFormat.FormatMock.defaultExpectation.params + mm_want_ptrs := mmFormat.FormatMock.defaultExpectation.paramPtrs + mm_got := CustomFormatterNameMockFormatParams{s1, p1} - if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + + if mm_want_ptrs != nil { + + if mm_want_ptrs.s1 != nil && !minimock.Equal(*mm_want_ptrs.s1, mm_got.s1) { + mmFormat.t.Errorf("CustomFormatterNameMock.Format got unexpected parameter s1, want: %#v, got: %#v%s\n", *mm_want_ptrs.s1, mm_got.s1, minimock.Diff(*mm_want_ptrs.s1, mm_got.s1)) + } + + if mm_want_ptrs.p1 != nil && !minimock.Equal(*mm_want_ptrs.p1, mm_got.p1) { + mmFormat.t.Errorf("CustomFormatterNameMock.Format got unexpected parameter p1, want: %#v, got: %#v%s\n", *mm_want_ptrs.p1, mm_got.p1, minimock.Diff(*mm_want_ptrs.p1, mm_got.p1)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { mmFormat.t.Errorf("CustomFormatterNameMock.Format got unexpected parameters, want: %#v, got: %#v%s\n", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) } @@ -213,21 +318,18 @@ func (mmFormat *mCustomFormatterNameMockFormat) Calls() []*CustomFormatterNameMo // MinimockFormatDone returns true if the count of the Format invocations corresponds // the number of defined expectations func (m *CustomFormatterNameMock) MinimockFormatDone() bool { + if m.FormatMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FormatMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false } } - // if default expectation was set then invocations count should be greater than zero - if m.FormatMock.defaultExpectation != nil && mm_atomic.LoadUint64(&m.afterFormatCounter) < 1 { - return false - } - // if func was set then invocations count should be greater than zero - if m.funcFormat != nil && mm_atomic.LoadUint64(&m.afterFormatCounter) < 1 { - return false - } - return true + return m.FormatMock.invocationsDone() } // MinimockFormatInspect logs each unmet expectation @@ -238,8 +340,9 @@ func (m *CustomFormatterNameMock) MinimockFormatInspect() { } } + afterFormatCounter := mm_atomic.LoadUint64(&m.afterFormatCounter) // if default expectation was set then invocations count should be greater than zero - if m.FormatMock.defaultExpectation != nil && mm_atomic.LoadUint64(&m.afterFormatCounter) < 1 { + if m.FormatMock.defaultExpectation != nil && afterFormatCounter < 1 { if m.FormatMock.defaultExpectation.params == nil { m.t.Error("Expected call to CustomFormatterNameMock.Format") } else { @@ -247,17 +350,23 @@ func (m *CustomFormatterNameMock) MinimockFormatInspect() { } } // if func was set then invocations count should be greater than zero - if m.funcFormat != nil && mm_atomic.LoadUint64(&m.afterFormatCounter) < 1 { + if m.funcFormat != nil && afterFormatCounter < 1 { m.t.Error("Expected call to CustomFormatterNameMock.Format") } + + if !m.FormatMock.invocationsDone() && afterFormatCounter > 0 { + m.t.Errorf("Expected %d calls to CustomFormatterNameMock.Format but found %d calls", + mm_atomic.LoadUint64(&m.FormatMock.expectedInvocations), afterFormatCounter) + } } // MinimockFinish checks that all mocked methods have been called the expected number of times func (m *CustomFormatterNameMock) MinimockFinish() { - if !m.minimockDone() { - m.MinimockFormatInspect() - m.t.FailNow() - } + m.finishOnce.Do(func() { + if !m.minimockDone() { + m.MinimockFormatInspect() + } + }) } // MinimockWait waits for all mocked methods to be called the expected number of times diff --git a/tests/formatter_with_custom_name_mock_test.go b/tests/formatter_with_custom_name_mock_test.go index 287185d..89fca3d 100644 --- a/tests/formatter_with_custom_name_mock_test.go +++ b/tests/formatter_with_custom_name_mock_test.go @@ -10,13 +10,18 @@ import ( ) func TestCustomFormatterNameMock_ImplementsStringer(t *testing.T) { - v := NewCustomFormatterNameMock(NewTesterMock(t)) + tester := NewTesterMock(t) + tester.CleanupMock.Return() + + v := NewCustomFormatterNameMock(tester) assert.True(t, reflect.TypeOf(v).Implements(reflect.TypeOf((*Formatter)(nil)).Elem())) } func TestCustomFormatterNameMock_UnmockedCallFailsTest(t *testing.T) { var mockCalled bool tester := NewTesterMock(t) + tester.CleanupMock.Return() + tester.FatalfMock.Set(func(s string, args ...interface{}) { assert.Equal(t, "Unexpected call to CustomFormatterNameMock.Format. %v %v", s) assert.Equal(t, "this call fails because Format method isn't mocked", args[0]) @@ -33,6 +38,7 @@ func TestCustomFormatterNameMock_UnmockedCallFailsTest(t *testing.T) { func TestCustomFormatterNameMock_MockedCallSucceeds(t *testing.T) { tester := NewTesterMock(t) + tester.CleanupMock.Return() formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.Set(func(format string, args ...interface{}) string { @@ -46,6 +52,7 @@ func TestCustomFormatterNameMock_MockedCallSucceeds(t *testing.T) { func TestCustomFormatterNameMock_Wait(t *testing.T) { tester := NewTesterMock(t) + tester.CleanupMock.Return() formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.Set(func(format string, args ...interface{}) string { @@ -62,6 +69,7 @@ func TestCustomFormatterNameMock_Wait(t *testing.T) { func TestCustomFormatterNameMock_Expect(t *testing.T) { tester := NewTesterMock(t) + tester.CleanupMock.Return() formatterMock := NewCustomFormatterNameMock(tester).FormatMock.Expect("Hello", "world", "!").Return("") @@ -75,6 +83,8 @@ func TestCustomFormatterNameMock_Expect(t *testing.T) { func TestCustomFormatterNameMock_ExpectDifferentArguments(t *testing.T) { assert.Panics(t, func() { tester := NewTesterMock(t) + tester.CleanupMock.Return() + defer tester.MinimockFinish() tester.ErrorfMock.Set(func(s string, args ...interface{}) { @@ -96,6 +106,8 @@ func TestCustomFormatterNameMock_ExpectAfterSet(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.FatalfMock.Expect("CustomFormatterNameMock.Format mock is already set by Set").Return() formatterMock := NewCustomFormatterNameMock(tester) @@ -108,6 +120,8 @@ func TestCustomFormatterNameMock_ExpectAfterWhen(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.FatalfMock.Expect("Expectation set by When has same params: %#v", CustomFormatterNameMockFormatParams{s1: "Should not work", p1: nil}).Return() formatterMock := NewCustomFormatterNameMock(tester) @@ -120,6 +134,7 @@ func TestCustomFormatterNameMock_ExpectAfterWhen(t *testing.T) { func TestCustomFormatterNameMock_Return(t *testing.T) { tester := NewTesterMock(t) + tester.CleanupMock.Return() formatterMock := NewCustomFormatterNameMock(tester).FormatMock.Return("Hello world!") df := dummyFormatter{formatterMock} @@ -130,6 +145,8 @@ func TestCustomFormatterNameMock_ReturnAfterSet(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.FatalfMock.Expect("CustomFormatterNameMock.Format mock is already set by Set").Return() formatterMock := NewCustomFormatterNameMock(tester) @@ -144,8 +161,9 @@ func TestCustomFormatterNameMock_ReturnWithoutExpectForFixedArgsMethod(t *testin tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.ErrorMock.Expect("Expected call to CustomFormatterNameMock.Format") - tester.FailNowMock.Expect() formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.Return("") @@ -154,6 +172,7 @@ func TestCustomFormatterNameMock_ReturnWithoutExpectForFixedArgsMethod(t *testin func TestCustomFormatterNameMock_Set(t *testing.T) { tester := NewTesterMock(t) + tester.CleanupMock.Return() formatterMock := NewCustomFormatterNameMock(tester).FormatMock.Set(func(string, ...interface{}) string { return "set" @@ -167,6 +186,8 @@ func TestCustomFormatterNameMock_SetAfterExpect(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.FatalfMock.Expect("Default expectation is already set for the Formatter.Format method").Return() formatterMock := NewCustomFormatterNameMock(tester).FormatMock.Expect("").Return("") @@ -179,6 +200,8 @@ func TestCustomFormatterNameMock_SetAfterWhen(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.FatalfMock.Expect("Some expectations are already set for the Formatter.Format method").Return() formatterMock := NewCustomFormatterNameMock(tester).FormatMock.When("").Then("") @@ -202,6 +225,8 @@ func TestCustomFormatterNameMockFormat_WhenAfterSet(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.FatalfMock.Expect("CustomFormatterNameMock.Format mock is already set by Set").Return() formatterMock := NewCustomFormatterNameMock(tester) @@ -211,12 +236,15 @@ func TestCustomFormatterNameMockFormat_WhenAfterSet(t *testing.T) { } func TestCustomFormatterNameMock_MinimockFormatDone(t *testing.T) { - formatterMock := NewCustomFormatterNameMock(t) + tester := NewTesterMock(t) + tester.CleanupMock.Return() + + formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.expectations = []*CustomFormatterNameMockFormatExpectation{{}} assert.False(t, formatterMock.MinimockFormatDone()) - formatterMock = NewCustomFormatterNameMock(t) + formatterMock = NewCustomFormatterNameMock(tester) formatterMock.FormatMock.defaultExpectation = &CustomFormatterNameMockFormatExpectation{} assert.False(t, formatterMock.MinimockFormatDone()) } @@ -225,8 +253,9 @@ func TestCustomFormatterNameMock_MinimockFinish(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.ErrorMock.Expect("Expected call to CustomFormatterNameMock.Format").Return() - tester.FailNowMock.Expect().Return() formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.Set(func(string, ...interface{}) string { return "" }) @@ -238,10 +267,11 @@ func TestCustomFormatterNameMock_MinimockFinish_WithNoMetExpectations(t *testing tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.ErrorfMock.Set(func(m string, args ...interface{}) { assert.Equal(t, m, "Expected call to CustomFormatterNameMock.Format with params: %#v") }) - tester.FailNowMock.Expect().Return() formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.Expect("a").Return("a") @@ -254,8 +284,9 @@ func TestCustomFormatterNameMock_MinimockWait(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + tester.ErrorMock.Expect("Expected call to CustomFormatterNameMock.Format").Return() - tester.FailNowMock.Expect().Return() formatterMock := NewCustomFormatterNameMock(tester) formatterMock.FormatMock.Set(func(string, ...interface{}) string { return "" }) @@ -268,6 +299,8 @@ func TestCustomFormatterNameMock_CallsNotNil(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + formatterMock := NewCustomFormatterNameMock(tester) calls := formatterMock.FormatMock.Calls() @@ -280,6 +313,8 @@ func TestCustomFormatterNameMock_Calls(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + // Arguments used for each mock call expected := []*CustomFormatterNameMockFormatParams{ {"a1", []interface{}{}}, @@ -303,6 +338,8 @@ func TestCustomFormatterNameMock_CallsReturnsCopy(t *testing.T) { tester := NewTesterMock(t) defer tester.MinimockFinish() + tester.CleanupMock.Return() + expected := []*CustomFormatterNameMockFormatParams{ {"a1", []interface{}{"a1"}}, {"b1", []interface{}{"b2"}}, diff --git a/tests/generic_complex_union.go b/tests/generic_complex_union.go index 42d66ae..195a97f 100644 --- a/tests/generic_complex_union.go +++ b/tests/generic_complex_union.go @@ -41,6 +41,7 @@ func NewGenericComplexUnionMock[T complexUnion](t minimock.Tester) *GenericCompl } type mGenericComplexUnionMockName[T complexUnion] struct { + optional bool mock *GenericComplexUnionMock[T] defaultExpectation *GenericComplexUnionMockNameExpectation[T] expectations []*GenericComplexUnionMockNameExpectation[T] @@ -70,6 +71,16 @@ type GenericComplexUnionMockNameParamPtrs[T complexUnion] struct { t1 *T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericComplexUnionMockName[T]) Optional() *mGenericComplexUnionMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericComplexUnion.Name func (mmName *mGenericComplexUnionMockName[T]) Expect(t1 T) *mGenericComplexUnionMockName[T] { if mmName.mock.funcName != nil { @@ -251,6 +262,11 @@ func (mmName *mGenericComplexUnionMockName[T]) Calls() []*GenericComplexUnionMoc // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericComplexUnionMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -293,7 +309,6 @@ func (m *GenericComplexUnionMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_in.go b/tests/generic_in.go index f77e549..fd6df26 100644 --- a/tests/generic_in.go +++ b/tests/generic_in.go @@ -41,6 +41,7 @@ func NewGenericInMock[T any](t minimock.Tester) *GenericInMock[T] { } type mGenericInMockName[T any] struct { + optional bool mock *GenericInMock[T] defaultExpectation *GenericInMockNameExpectation[T] expectations []*GenericInMockNameExpectation[T] @@ -70,6 +71,16 @@ type GenericInMockNameParamPtrs[T any] struct { t1 *T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericInMockName[T]) Optional() *mGenericInMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericIn.Name func (mmName *mGenericInMockName[T]) Expect(t1 T) *mGenericInMockName[T] { if mmName.mock.funcName != nil { @@ -251,6 +262,11 @@ func (mmName *mGenericInMockName[T]) Calls() []*GenericInMockNameParams[T] { // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericInMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -293,7 +309,6 @@ func (m *GenericInMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_inline_union.go b/tests/generic_inline_union.go index 59b69c2..25b65a6 100644 --- a/tests/generic_inline_union.go +++ b/tests/generic_inline_union.go @@ -41,6 +41,7 @@ func NewGenericInlineUnionMock[T int | float64](t minimock.Tester) *GenericInlin } type mGenericInlineUnionMockName[T int | float64] struct { + optional bool mock *GenericInlineUnionMock[T] defaultExpectation *GenericInlineUnionMockNameExpectation[T] expectations []*GenericInlineUnionMockNameExpectation[T] @@ -70,6 +71,16 @@ type GenericInlineUnionMockNameParamPtrs[T int | float64] struct { t1 *T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericInlineUnionMockName[T]) Optional() *mGenericInlineUnionMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericInlineUnion.Name func (mmName *mGenericInlineUnionMockName[T]) Expect(t1 T) *mGenericInlineUnionMockName[T] { if mmName.mock.funcName != nil { @@ -251,6 +262,11 @@ func (mmName *mGenericInlineUnionMockName[T]) Calls() []*GenericInlineUnionMockN // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericInlineUnionMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -293,7 +309,6 @@ func (m *GenericInlineUnionMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_inline_with_many_options.go b/tests/generic_inline_with_many_options.go index b640bae..f729925 100644 --- a/tests/generic_inline_with_many_options.go +++ b/tests/generic_inline_with_many_options.go @@ -41,6 +41,7 @@ func NewGenericInlineUnionWithManyTypesMock[T int | float64 | string](t minimock } type mGenericInlineUnionWithManyTypesMockName[T int | float64 | string] struct { + optional bool mock *GenericInlineUnionWithManyTypesMock[T] defaultExpectation *GenericInlineUnionWithManyTypesMockNameExpectation[T] expectations []*GenericInlineUnionWithManyTypesMockNameExpectation[T] @@ -70,6 +71,16 @@ type GenericInlineUnionWithManyTypesMockNameParamPtrs[T int | float64 | string] t1 *T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericInlineUnionWithManyTypesMockName[T]) Optional() *mGenericInlineUnionWithManyTypesMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericInlineUnionWithManyTypes.Name func (mmName *mGenericInlineUnionWithManyTypesMockName[T]) Expect(t1 T) *mGenericInlineUnionWithManyTypesMockName[T] { if mmName.mock.funcName != nil { @@ -251,6 +262,11 @@ func (mmName *mGenericInlineUnionWithManyTypesMockName[T]) Calls() []*GenericInl // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericInlineUnionWithManyTypesMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -293,7 +309,6 @@ func (m *GenericInlineUnionWithManyTypesMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_inout.go b/tests/generic_inout.go index 6808faa..7d51a04 100644 --- a/tests/generic_inout.go +++ b/tests/generic_inout.go @@ -41,6 +41,7 @@ func NewGenericInoutMock[T any](t minimock.Tester) *GenericInoutMock[T] { } type mGenericInoutMockName[T any] struct { + optional bool mock *GenericInoutMock[T] defaultExpectation *GenericInoutMockNameExpectation[T] expectations []*GenericInoutMockNameExpectation[T] @@ -75,6 +76,16 @@ type GenericInoutMockNameResults[T any] struct { t2 T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericInoutMockName[T]) Optional() *mGenericInoutMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericInout.Name func (mmName *mGenericInoutMockName[T]) Expect(t1 T) *mGenericInoutMockName[T] { if mmName.mock.funcName != nil { @@ -279,6 +290,11 @@ func (mmName *mGenericInoutMockName[T]) Calls() []*GenericInoutMockNameParams[T] // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericInoutMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -321,7 +337,6 @@ func (m *GenericInoutMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_multiple_args_with_different_types.go b/tests/generic_multiple_args_with_different_types.go index 1df9d2e..e435c42 100644 --- a/tests/generic_multiple_args_with_different_types.go +++ b/tests/generic_multiple_args_with_different_types.go @@ -42,6 +42,7 @@ func NewGenericMultipleTypesMock[T proto.Message, K any](t minimock.Tester) *Gen } type mGenericMultipleTypesMockName[T proto.Message, K any] struct { + optional bool mock *GenericMultipleTypesMock[T, K] defaultExpectation *GenericMultipleTypesMockNameExpectation[T, K] expectations []*GenericMultipleTypesMockNameExpectation[T, K] @@ -73,6 +74,16 @@ type GenericMultipleTypesMockNameParamPtrs[T proto.Message, K any] struct { k1 *K } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericMultipleTypesMockName[T, K]) Optional() *mGenericMultipleTypesMockName[T, K] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericMultipleTypes.Name func (mmName *mGenericMultipleTypesMockName[T, K]) Expect(t1 T, k1 K) *mGenericMultipleTypesMockName[T, K] { if mmName.mock.funcName != nil { @@ -280,6 +291,11 @@ func (mmName *mGenericMultipleTypesMockName[T, K]) Calls() []*GenericMultipleTyp // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericMultipleTypesMock[T, K]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -322,7 +338,6 @@ func (m *GenericMultipleTypesMock[T, K]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_out.go b/tests/generic_out.go index 916ad47..b81d64c 100644 --- a/tests/generic_out.go +++ b/tests/generic_out.go @@ -40,6 +40,7 @@ func NewGenericOutMock[T any](t minimock.Tester) *GenericOutMock[T] { } type mGenericOutMockName[T any] struct { + optional bool mock *GenericOutMock[T] defaultExpectation *GenericOutMockNameExpectation[T] expectations []*GenericOutMockNameExpectation[T] @@ -60,6 +61,16 @@ type GenericOutMockNameResults[T any] struct { t1 T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericOutMockName[T]) Optional() *mGenericOutMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericOut.Name func (mmName *mGenericOutMockName[T]) Expect() *mGenericOutMockName[T] { if mmName.mock.funcName != nil { @@ -169,6 +180,11 @@ func (mmName *GenericOutMock[T]) NameBeforeCounter() uint64 { // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericOutMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -207,7 +223,6 @@ func (m *GenericOutMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_simple_union.go b/tests/generic_simple_union.go index 0b06bda..9088970 100644 --- a/tests/generic_simple_union.go +++ b/tests/generic_simple_union.go @@ -41,6 +41,7 @@ func NewGenericSimpleUnionMock[T simpleUnion](t minimock.Tester) *GenericSimpleU } type mGenericSimpleUnionMockName[T simpleUnion] struct { + optional bool mock *GenericSimpleUnionMock[T] defaultExpectation *GenericSimpleUnionMockNameExpectation[T] expectations []*GenericSimpleUnionMockNameExpectation[T] @@ -70,6 +71,16 @@ type GenericSimpleUnionMockNameParamPtrs[T simpleUnion] struct { t1 *T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericSimpleUnionMockName[T]) Optional() *mGenericSimpleUnionMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericSimpleUnion.Name func (mmName *mGenericSimpleUnionMockName[T]) Expect(t1 T) *mGenericSimpleUnionMockName[T] { if mmName.mock.funcName != nil { @@ -251,6 +262,11 @@ func (mmName *mGenericSimpleUnionMockName[T]) Calls() []*GenericSimpleUnionMockN // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericSimpleUnionMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -293,7 +309,6 @@ func (m *GenericSimpleUnionMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/generic_specific.go b/tests/generic_specific.go index 78ee0d2..667cd73 100644 --- a/tests/generic_specific.go +++ b/tests/generic_specific.go @@ -42,6 +42,7 @@ func NewGenericSpecificMock[T proto.Message](t minimock.Tester) *GenericSpecific } type mGenericSpecificMockName[T proto.Message] struct { + optional bool mock *GenericSpecificMock[T] defaultExpectation *GenericSpecificMockNameExpectation[T] expectations []*GenericSpecificMockNameExpectation[T] @@ -71,6 +72,16 @@ type GenericSpecificMockNameParamPtrs[T proto.Message] struct { t1 *T } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmName *mGenericSpecificMockName[T]) Optional() *mGenericSpecificMockName[T] { + mmName.optional = true + return mmName +} + // Expect sets up expected params for genericSpecific.Name func (mmName *mGenericSpecificMockName[T]) Expect(t1 T) *mGenericSpecificMockName[T] { if mmName.mock.funcName != nil { @@ -252,6 +263,11 @@ func (mmName *mGenericSpecificMockName[T]) Calls() []*GenericSpecificMockNamePar // MinimockNameDone returns true if the count of the Name invocations corresponds // the number of defined expectations func (m *GenericSpecificMock[T]) MinimockNameDone() bool { + if m.NameMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.NameMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -294,7 +310,6 @@ func (m *GenericSpecificMock[T]) MinimockFinish() { m.finishOnce.Do(func() { if !m.minimockDone() { m.MinimockNameInspect() - m.t.FailNow() } }) } diff --git a/tests/package_name_specified_test.go b/tests/package_name_specified_test.go index 1df2aa2..0fccc87 100644 --- a/tests/package_name_specified_test.go +++ b/tests/package_name_specified_test.go @@ -85,6 +85,7 @@ func NewTesterMock(t minimock.Tester) *TesterMock { } type mTesterMockCleanup struct { + optional bool mock *TesterMock defaultExpectation *TesterMockCleanupExpectation expectations []*TesterMockCleanupExpectation @@ -114,6 +115,16 @@ type TesterMockCleanupParamPtrs struct { f *func() } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmCleanup *mTesterMockCleanup) Optional() *mTesterMockCleanup { + mmCleanup.optional = true + return mmCleanup +} + // Expect sets up expected params for Tester.Cleanup func (mmCleanup *mTesterMockCleanup) Expect(f func()) *mTesterMockCleanup { if mmCleanup.mock.funcCleanup != nil { @@ -295,6 +306,11 @@ func (mmCleanup *mTesterMockCleanup) Calls() []*TesterMockCleanupParams { // MinimockCleanupDone returns true if the count of the Cleanup invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockCleanupDone() bool { + if m.CleanupMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.CleanupMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -333,6 +349,7 @@ func (m *TesterMock) MinimockCleanupInspect() { } type mTesterMockError struct { + optional bool mock *TesterMock defaultExpectation *TesterMockErrorExpectation expectations []*TesterMockErrorExpectation @@ -362,6 +379,16 @@ type TesterMockErrorParamPtrs struct { p1 *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmError *mTesterMockError) Optional() *mTesterMockError { + mmError.optional = true + return mmError +} + // Expect sets up expected params for Tester.Error func (mmError *mTesterMockError) Expect(p1 ...interface{}) *mTesterMockError { if mmError.mock.funcError != nil { @@ -543,6 +570,11 @@ func (mmError *mTesterMockError) Calls() []*TesterMockErrorParams { // MinimockErrorDone returns true if the count of the Error invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockErrorDone() bool { + if m.ErrorMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ErrorMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -581,6 +613,7 @@ func (m *TesterMock) MinimockErrorInspect() { } type mTesterMockErrorf struct { + optional bool mock *TesterMock defaultExpectation *TesterMockErrorfExpectation expectations []*TesterMockErrorfExpectation @@ -612,6 +645,16 @@ type TesterMockErrorfParamPtrs struct { args *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmErrorf *mTesterMockErrorf) Optional() *mTesterMockErrorf { + mmErrorf.optional = true + return mmErrorf +} + // Expect sets up expected params for Tester.Errorf func (mmErrorf *mTesterMockErrorf) Expect(format string, args ...interface{}) *mTesterMockErrorf { if mmErrorf.mock.funcErrorf != nil { @@ -819,6 +862,11 @@ func (mmErrorf *mTesterMockErrorf) Calls() []*TesterMockErrorfParams { // MinimockErrorfDone returns true if the count of the Errorf invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockErrorfDone() bool { + if m.ErrorfMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ErrorfMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -857,6 +905,7 @@ func (m *TesterMock) MinimockErrorfInspect() { } type mTesterMockFailNow struct { + optional bool mock *TesterMock defaultExpectation *TesterMockFailNowExpectation expectations []*TesterMockFailNowExpectation @@ -871,6 +920,16 @@ type TesterMockFailNowExpectation struct { Counter uint64 } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFailNow *mTesterMockFailNow) Optional() *mTesterMockFailNow { + mmFailNow.optional = true + return mmFailNow +} + // Expect sets up expected params for Tester.FailNow func (mmFailNow *mTesterMockFailNow) Expect() *mTesterMockFailNow { if mmFailNow.mock.funcFailNow != nil { @@ -978,6 +1037,11 @@ func (mmFailNow *TesterMock) FailNowBeforeCounter() uint64 { // MinimockFailNowDone returns true if the count of the FailNow invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockFailNowDone() bool { + if m.FailNowMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FailNowMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1012,6 +1076,7 @@ func (m *TesterMock) MinimockFailNowInspect() { } type mTesterMockFatal struct { + optional bool mock *TesterMock defaultExpectation *TesterMockFatalExpectation expectations []*TesterMockFatalExpectation @@ -1041,6 +1106,16 @@ type TesterMockFatalParamPtrs struct { args *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFatal *mTesterMockFatal) Optional() *mTesterMockFatal { + mmFatal.optional = true + return mmFatal +} + // Expect sets up expected params for Tester.Fatal func (mmFatal *mTesterMockFatal) Expect(args ...interface{}) *mTesterMockFatal { if mmFatal.mock.funcFatal != nil { @@ -1222,6 +1297,11 @@ func (mmFatal *mTesterMockFatal) Calls() []*TesterMockFatalParams { // MinimockFatalDone returns true if the count of the Fatal invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockFatalDone() bool { + if m.FatalMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FatalMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1260,6 +1340,7 @@ func (m *TesterMock) MinimockFatalInspect() { } type mTesterMockFatalf struct { + optional bool mock *TesterMock defaultExpectation *TesterMockFatalfExpectation expectations []*TesterMockFatalfExpectation @@ -1291,6 +1372,16 @@ type TesterMockFatalfParamPtrs struct { args *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFatalf *mTesterMockFatalf) Optional() *mTesterMockFatalf { + mmFatalf.optional = true + return mmFatalf +} + // Expect sets up expected params for Tester.Fatalf func (mmFatalf *mTesterMockFatalf) Expect(format string, args ...interface{}) *mTesterMockFatalf { if mmFatalf.mock.funcFatalf != nil { @@ -1498,6 +1589,11 @@ func (mmFatalf *mTesterMockFatalf) Calls() []*TesterMockFatalfParams { // MinimockFatalfDone returns true if the count of the Fatalf invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockFatalfDone() bool { + if m.FatalfMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FatalfMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1550,7 +1646,6 @@ func (m *TesterMock) MinimockFinish() { m.MinimockFatalInspect() m.MinimockFatalfInspect() - m.t.FailNow() } }) } diff --git a/tests/tester_mock_test.go b/tests/tester_mock_test.go index 146ddf0..93f2f73 100644 --- a/tests/tester_mock_test.go +++ b/tests/tester_mock_test.go @@ -85,6 +85,7 @@ func NewTesterMock(t minimock.Tester) *TesterMock { } type mTesterMockCleanup struct { + optional bool mock *TesterMock defaultExpectation *TesterMockCleanupExpectation expectations []*TesterMockCleanupExpectation @@ -114,6 +115,16 @@ type TesterMockCleanupParamPtrs struct { f *func() } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmCleanup *mTesterMockCleanup) Optional() *mTesterMockCleanup { + mmCleanup.optional = true + return mmCleanup +} + // Expect sets up expected params for Tester.Cleanup func (mmCleanup *mTesterMockCleanup) Expect(f func()) *mTesterMockCleanup { if mmCleanup.mock.funcCleanup != nil { @@ -295,6 +306,11 @@ func (mmCleanup *mTesterMockCleanup) Calls() []*TesterMockCleanupParams { // MinimockCleanupDone returns true if the count of the Cleanup invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockCleanupDone() bool { + if m.CleanupMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.CleanupMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -333,6 +349,7 @@ func (m *TesterMock) MinimockCleanupInspect() { } type mTesterMockError struct { + optional bool mock *TesterMock defaultExpectation *TesterMockErrorExpectation expectations []*TesterMockErrorExpectation @@ -362,6 +379,16 @@ type TesterMockErrorParamPtrs struct { p1 *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmError *mTesterMockError) Optional() *mTesterMockError { + mmError.optional = true + return mmError +} + // Expect sets up expected params for Tester.Error func (mmError *mTesterMockError) Expect(p1 ...interface{}) *mTesterMockError { if mmError.mock.funcError != nil { @@ -543,6 +570,11 @@ func (mmError *mTesterMockError) Calls() []*TesterMockErrorParams { // MinimockErrorDone returns true if the count of the Error invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockErrorDone() bool { + if m.ErrorMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ErrorMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -581,6 +613,7 @@ func (m *TesterMock) MinimockErrorInspect() { } type mTesterMockErrorf struct { + optional bool mock *TesterMock defaultExpectation *TesterMockErrorfExpectation expectations []*TesterMockErrorfExpectation @@ -612,6 +645,16 @@ type TesterMockErrorfParamPtrs struct { args *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmErrorf *mTesterMockErrorf) Optional() *mTesterMockErrorf { + mmErrorf.optional = true + return mmErrorf +} + // Expect sets up expected params for Tester.Errorf func (mmErrorf *mTesterMockErrorf) Expect(format string, args ...interface{}) *mTesterMockErrorf { if mmErrorf.mock.funcErrorf != nil { @@ -819,6 +862,11 @@ func (mmErrorf *mTesterMockErrorf) Calls() []*TesterMockErrorfParams { // MinimockErrorfDone returns true if the count of the Errorf invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockErrorfDone() bool { + if m.ErrorfMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.ErrorfMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -857,6 +905,7 @@ func (m *TesterMock) MinimockErrorfInspect() { } type mTesterMockFailNow struct { + optional bool mock *TesterMock defaultExpectation *TesterMockFailNowExpectation expectations []*TesterMockFailNowExpectation @@ -871,6 +920,16 @@ type TesterMockFailNowExpectation struct { Counter uint64 } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFailNow *mTesterMockFailNow) Optional() *mTesterMockFailNow { + mmFailNow.optional = true + return mmFailNow +} + // Expect sets up expected params for Tester.FailNow func (mmFailNow *mTesterMockFailNow) Expect() *mTesterMockFailNow { if mmFailNow.mock.funcFailNow != nil { @@ -978,6 +1037,11 @@ func (mmFailNow *TesterMock) FailNowBeforeCounter() uint64 { // MinimockFailNowDone returns true if the count of the FailNow invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockFailNowDone() bool { + if m.FailNowMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FailNowMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1012,6 +1076,7 @@ func (m *TesterMock) MinimockFailNowInspect() { } type mTesterMockFatal struct { + optional bool mock *TesterMock defaultExpectation *TesterMockFatalExpectation expectations []*TesterMockFatalExpectation @@ -1041,6 +1106,16 @@ type TesterMockFatalParamPtrs struct { args *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFatal *mTesterMockFatal) Optional() *mTesterMockFatal { + mmFatal.optional = true + return mmFatal +} + // Expect sets up expected params for Tester.Fatal func (mmFatal *mTesterMockFatal) Expect(args ...interface{}) *mTesterMockFatal { if mmFatal.mock.funcFatal != nil { @@ -1222,6 +1297,11 @@ func (mmFatal *mTesterMockFatal) Calls() []*TesterMockFatalParams { // MinimockFatalDone returns true if the count of the Fatal invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockFatalDone() bool { + if m.FatalMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FatalMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1260,6 +1340,7 @@ func (m *TesterMock) MinimockFatalInspect() { } type mTesterMockFatalf struct { + optional bool mock *TesterMock defaultExpectation *TesterMockFatalfExpectation expectations []*TesterMockFatalfExpectation @@ -1291,6 +1372,16 @@ type TesterMockFatalfParamPtrs struct { args *[]interface{} } +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmFatalf *mTesterMockFatalf) Optional() *mTesterMockFatalf { + mmFatalf.optional = true + return mmFatalf +} + // Expect sets up expected params for Tester.Fatalf func (mmFatalf *mTesterMockFatalf) Expect(format string, args ...interface{}) *mTesterMockFatalf { if mmFatalf.mock.funcFatalf != nil { @@ -1498,6 +1589,11 @@ func (mmFatalf *mTesterMockFatalf) Calls() []*TesterMockFatalfParams { // MinimockFatalfDone returns true if the count of the Fatalf invocations corresponds // the number of defined expectations func (m *TesterMock) MinimockFatalfDone() bool { + if m.FatalfMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + for _, e := range m.FatalfMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false @@ -1550,7 +1646,6 @@ func (m *TesterMock) MinimockFinish() { m.MinimockFatalInspect() m.MinimockFatalfInspect() - m.t.FailNow() } }) }