Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xpepper/11c85e3fa7e0349001cac846b7cab4e9 to your computer and use it in GitHub Desktop.
Save xpepper/11c85e3fa7e0349001cac846b7cab4e9 to your computer and use it in GitHub Desktop.
title tags disqus
Trade-offs to consider when choosing to use Mocks vs Fakes
testing
pierodibello

Hi there! Today we had a nice conversation in my team around the use of mocks vs fakes in doing TDD (I'm referring to mocks and fakes as defined by Fowler and Meszaros in TestDouble).

The topic was: when should I use a mock instead of a fake, and why? What are the main trade-offs to consider when doing this kind of choice?

My list of pros and cons, off the top of my head, was:

Fakes

  • -1 slower to go from red to green bar in a test (I need to stop and implement by hand the fake, even if really dumb and simple)
  • -1 more time spent keeping them up-to-date
  • -1 to test exceptions I need to have different fakes, e.g. a AlwaysFailingUserRepository, that is more boilerplate to handle, more lines of code in my test codebase, etc.
  • -1 what should I do if the fake starts having a non-trivial logic?
  • +1 easier to have test loosely coupled to the actual implementation of the object under test, and this means your test will be insensible to structural changes
  • +1 fakes are a great tool to support a strong functional splitting and slicing of a feature (e.g. I can release to production wiring my classes with a fake service and with a simplified feature, even without the "real" implementation of the service developed)
  • +1 fakes also helps in doing trunk-based development (I can always merge to master with a fake instead of the real implementation I'm still developing)

Mocks

  • +1 faster to use to go from red to green in a test (and somehow even easier to "design" the interaction between the object under tests and its collaborators while doing the test)
  • +1 mocks are transparently in sync with the interface that they're mocking (no code to change)
  • -1 may slow down refactoring (especially when you over-use or abuse of mocks) because of the higher coupling between your tests and the actual implementation of the object under test. This means that your tests are more fragile, because more sensible to structural changes (on this topic, see this great post by Kent Beck)

BTW, as my friend @matteo.pierro told me, both those kind of test doubles (and all test doubles indeed) suffer of the issue that you still need some other kind of test (an "integration test"? some contract-driven approach?) to check that the fake/mock implementation is behaving like the real dependency.

What do you think? :thinking_face: What are the trade-off you take into consideration when choosing which kind of test double to use in your TDD process?

Reactions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment