3 ms·
I'll give my 2 cents (which may or may not be worth it ;-) ). Mocks are useful when you are doing TDD. At some point you have to build something which will ne
by mikekchar 11y ago
I'll give my 2 cents (which may or may not be worth it ;-) ).
Mocks are useful when you are doing TDD. At some point you have to build something which will need several collaborators, but the collaborators have not been built yet. You're not sure yet what final shape the design should take, so it's great to build an object, mocking the collaborators. You can then build the collaborators. This allows you to refactor your design easily and quickly when you are in this early stage. It's easy to change the interface of an object that hasn't been written yet ;-) Then when you implement the mocked object, it's easy to write because you just implement the bits that were mocked.
At this point, I tend to replace my mocks with real objects. The reason for this is almost exactly the same reason for using mocks initially (ironically): mocked objects make your design hard to refactor. If I change the interface for an object, then anything that has mocked that interface needs to have its tests updated. This is not hard, but is crappy enough that it stops people from refactoring their interfaces. When you are using real objects all the way through, you often only need to change the production code and the unit tests for the object whose interface you changed.
Real objects in tests are also really useful for documentation purposes. When you use real objects you have to show how to build the objects and how all the collaborators work. Some people tend to think that this is "integration testing" and should not be done in unit tests. I disagree fairly strongly with that idea, but I would be remiss if I didn't acknowledge that some of the anti-real-objects-in-unit-test people are pretty smart people ;-)
Obviously real objects are safer to use as there are ways to confuse yourself with mocks so that you don't actually test anything meaningful.
The main downsides with real objects is: sometimes you have to build the world to make them, and sometimes the real object has some external dependency which makes testing with them infeasible. The first issue is often a sign of poor design and should be rare -- but of course life happens. The second issue is usually not something you can control. In these circumstances, I will prefer to use mocks. In some circumstances you end up having to make mocks of mocks, or reaching down into structures you shouldn't know about. In those cases I prefer to use fakes.
All of these techniques are valid and useful techniques. In any non-toy problem you will have to use all of them to have a good test system. The trick is knowing when you should be using each. That requires some experience.