docker-archive / deploykit

A toolkit for creating and managing declarative, self-healing infrastructure.
Apache License 2.0
2.25k stars 262 forks source link

Consider gomock alternatives #187

Open stevvooe opened 8 years ago

stevvooe commented 8 years ago

We've found that gomock introduces more problems than it solves. I'd recommend removing it and replacing with simple interface embedding. The following provides the same functionality as gomock:

type myMock struct {
  MockedInterface
}

// Override will intercept override.
func (m *myMock) Override(...) { }

Wish I could have warned you earlier.

chungers commented 8 years ago

Yeah I am not a big fan of gomock. The generated code often have problems with I turned on go test -race

wfarner commented 8 years ago

I actually went in with both eyes open here, and found your notes on gomock while researching what to use for mocking :-)

My only concern with hand-rolled fakes is that we end up with many mock-like struct implementations anyway, particularly in instances where we care about call counts or order. Additionally, i imagine it will become onerous to write these fakes as you want to introduce multiple test cases where the mock/fake has slightly different behavior.

All that said, i'm also not totally satisfied with gomock; particularly since it does not appear to be actively maintained. We should mull this over and decide how to proceed.

groob commented 8 years ago

What about creating a mock struct like the ones in @benbjohnson's example?

Given an interface, these can all be easily generated with a tool like impl.

wfarner commented 8 years ago

@groob that approach could indeed work really well, thanks for the pointer!

stevvooe commented 8 years ago

@groob @wfarner The example provided is similar to what I'm suggesting. Typically, I've build this up as required. I go into this somewhat in https://github.com/golang/mock/pull/35#r64802424.

Generation may work here, but it may be enough to provide a few helpers to serialize, compare and count function calls. In Go, heavyweight solutions tend to cause more problems than they create. For mocks, creating a mock type per test or set of tests is usually enough to confirm a behavior.

zachgersh commented 8 years ago

@stevvooe - I do quite a bit of mock based testing and can't say enough good things about counterfeiter:

https://github.com/maxbrunsfeld/counterfeiter

Some of the major benefits

the example in the repo is a bit sparse but you can totally look at a more specific implementation I have done here:

Implementation: https://github.com/concourse/bosh-io-stemcell-resource/blob/master/fakes/bar.go

Declaration on top of interface: https://github.com/concourse/bosh-io-stemcell-resource/blob/master/boshio/boshio.go#L18