Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a helper method for inline setup of mocks #133

Open
mniak opened this issue Dec 21, 2023 · 1 comment
Open

Add a helper method for inline setup of mocks #133

mniak opened this issue Dec 21, 2023 · 1 comment

Comments

@mniak
Copy link

mniak commented Dec 21, 2023

Requested feature
A helper method that would make inline construction of mocks possible.

Why the feature is needed

So the test code would look nicer

Proposed solution

Maybe something like a SETUP method in every mock, which woul receive a function that configures the mock.

Example (before):

ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockReader1 := NewMockDep1(ctrl)
mockReader1.EXPECT().
    ReadSomething(gomock.Any(), gomock.Any()).
    Return("first call", nil)
mockReader1.EXPECT().
    ReadSomething(gomock.Any(), gomock.Any()).
    Return("second call", nil)
mockReader1.EXPECT().
    ReadSomething(gomock.Any(), gomock.Any()).
    Return("third call", nil)

mockWriter := NewMockDep1(ctrl)
mockWriter.EXPECT().
    WriteSomething(gomock.Any(), gomock.Any()).
    Return("first call", nil)
mockWriter.EXPECT().
    WriteSomething(gomock.Any(), gomock.Any()).
    Return("second call", nil)
mockWriter.EXPECT().
    WriteSomething(gomock.Any(), gomock.Any()).
    Return("third call", nil)

sut := NewSystemUnderTest(mockReader, mockWriter)
sut.DoAction()

Example (after):

ctrl := gomock.NewController(t)
defer ctrl.Finish()

sut := NewSystemUnderTest(
    NewMockReader(ctrl).SETUP(func (mock *MockReader) {
        mock.EXPECT().
            ReadSomething(gomock.Any(), gomock.Any()).
            Return("first call", nil)
        mock.EXPECT().
            ReadSomething(gomock.Any(), gomock.Any()).
            Return("second call", nil)
        mock.EXPECT().
            ReadSomething(gomock.Any(), gomock.Any()).
            Return("third call", nil)
    }),
    NewMockWriter(ctrl).SETUP(func (mock *MockWriter) {
        mock.EXPECT().
            WriteSomething(gomock.Any(), gomock.Any()).
            Return("first call", nil)
        mock.EXPECT().
            WriteSomething(gomock.Any(), gomock.Any()).
            Return("second call", nil)
        mock.EXPECT().
            WriteSomething(gomock.Any(), gomock.Any()).
            Return("third call", nil)
    }),
)
sut.DoAction()
@r-hang
Copy link
Contributor

r-hang commented Dec 26, 2023

I think I understand why this could reduce some hand-written function declarations if you wanted to re-use setup functions but it think that having multiple patterns for setting up mocks (one with a setup function and one without) would make mock code less uniform and make users uncertain about which approach to use (in most cases we want to reduce nesting).

From what I can tell the generated implementation would be a methods with a pointer receiver that takes in a variable with the same reference to the receiver when ideally there is one clear variable to modify.

If this is just for inline setup, would it be better to create external wrapper functions that you could call inline?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants