Just for the sake of discussion below, when I refer to mocking, I mean mocking/stubbing/faking, as contrast to use real implementation in testing
I just had some discussion with my colleague during a pair programming session regarding whether we should use mocking in unit tests for our own written code. (Not sure whether this matters, but we are pair programming on a Ruby/Rails code base)
His argument is that we should not use mocking if it's our own written code. Mocking should be used only to stuffs out external dependencies (.e.g. third party system). Let's say if there are class A and B, and A depends on B (.e.g. one of A's method creates and uses B), he said we should not mock B out when testing A (both A and B are written and maintained by us), since B is internal implementation details of A.
While I agree with him to some degree, I still find some cases where mocking our own code is necessary and required:
- First, I believe if we don't mock dependencies of a class, it's no longer unit test. So like above example, we are writing integration test for class A and B. I'm not saying integration tests are not needed, but there are some disadvantages of it compared to unit test, .e.g. run slower and when a test fails, you need to trace the implementation code to identify the components that cause the failure. And therefore we should make it clear what's unit test, what's integration test
- Second, we should not test and care about implementation details of a class as long as its public contract still maintains. However, I believe we should test a class's interaction with its (peer?)dependencies since those interactions are expected behaviors of that class. In some cases, it's not easy to determine what is implementation details and what is dependency, .e.g. in a layered application (controller -> application service -> domain), is an application service dependency or internal implementation of a controller?
So my questions are:
- What are your opinions on when and where to use mocking?
- Any good heuristics to decide what is dependency and what is internal implementation details? Take for example the layered application above
Not sure whether it's because my background is in C#, I find it difficult to accept the idea of mocking is not needed when testing our own code