golang / mock

GoMock is a mocking framework for the Go programming language.
Apache License 2.0
9.3k stars 609 forks source link

Allow generating loose/dynamic mocks #7

Closed liron-l closed 3 years ago

liron-l commented 9 years ago

Multiple mocking framework support both loose/dynamic and strict mocks*. I propose adding support for generting such mocks as part of the mock generation api

loose := mocks.NewMyDynamicMock(ctrl)
strict := mocks.NewMyMock(ctrl)

or

strict := mocks.NewMyMock(ctrl)
loose := strict.Dynamic = true

Both solution are backward compatible. I would like to hear your feedback about the idea.

**loose/dynamic - mock that doesn't panic when unregistered method is called

dsymonds commented 9 years ago

It's plausible, though in my experience if you're looking for a loose mock then you'd be better served by either a hand-written fake/stub, or merely expecting the relevant methods with .AnyTimes().

mariusstaicu commented 7 years ago

Is there any update on this in the last two years ?

codyoss commented 4 years ago

I am not against this idea, but I would love to hear what others would expect to see here.

skplunkerin commented 4 years ago

I would love this ability. I've been feeling like my mock tests are messier than they need to be. I'd rather they be concise to exactly what I'm testing.

I like the loose := strict.Dynamic = true idea, but not if I need to have several lines, setting every single mock to Dynamic == true, so if there was a way to specify multiple mocks as dynamic vs not would be ideal. The first suggestion of loose := mocks.NewMyDynamicMock(ctrl) would work for this better 🤔

If the loose/dynamic approach isn't desirable, then perhaps something similar to what Mocha does in Ruby to help reduce the mocking friction. Mocha still fails the entire test like gomock does, but it offers a suggested code snippet when it happens.

Example:

p.s., I'm still very new to Go and gomock. I combined an error from one of my Go tests, with an example from Mocha. Please use the below as example only 🙏

API server listening at: 127.0.0.1:14090
--- FAIL: TestInstancePerform (0.00s)
    --- FAIL: TestInstancePerform/success (0.00s)
        instance.go:890: Unexpected call to *databasetest.MockTxInstanceJobsQueryer.Get([efa55e15-520d-4p39-b703-f962e7dc7008]) at /internal/testhelper/mock/databasetest/instance_job.go:204 because: there are no expected calls of the method "Get" for that receiver

        You can stub this request with the following snippet:

        instanceJobsMock.EXPECT().Get(gomock.AssignableToTypeOf(uuid.UUID{})).Return(
            &database.InstanceJob{
                Name: "success resource", 
                IsEnabled: true,
            }, 
            nil,
        )

        ============================================================
        panic.go:563: missing call(s) to *databasetest.MockTxInstanceJobsQueryer.Update(is assignable to UUID, is assignable to ) /testfile_test.go:1670
        panic.go:563: missing call(s) to *databasetest.MockTxInstancesQueryer.GetByID(is assignable to UUID) /testfile_test.go:1668
        panic.go:563: missing call(s) to *resourcetest.MockInstanceResourceHandler.Perform(is anything, is assignable to , is assignable to , is anything) /testfile_test.go:1669
        panic.go:563: aborting test due to missing call(s)
FAIL
codyoss commented 3 years ago

I am closing this issue in favor of #538. Future discussion on this topic will happen on that issue.