So I thought it was time to write a little about my lightning talk from the last Swedish ALT.NET unconference. First of all we must decide on what we mean when we say we’re mocking. Do we mean “using mock objects in our tests” or do we mean “using a mocking framework”? I prefer to use the definition of mock used by Martin Fowler which I’ve talked about earlier. From that definition it is clear that mock frameworks can be used to create any kind of test double, not only mocks. And you can use mock objects without using any mock framework. So personally I tend to stick with the interpretation that “mocking” means “using mock objects”.
Another interesting observation is that stubs according to Martin Fowler may record information about what calls are made. This makes stubs just as powerful in verifying actions as mocks. It also makes stubs very similar to mocks. So anything that can be mocked can also be stubbed. And vice versa.
So when looking at mocking I think mocking forces me to think about the implementation of the code I’m testing. I think this is bad since one of the great benefits from BDD/TDD in my opinion is the fact you don’t think about implementation until you really have to. Mocking frameworks of today are also so powerful that they can be used to mock objects and designs that are a little difficult to test. And if the mocking framework rescues you from a bad design I think it is questionable if you will ever learn and design your code better. Why do it if you don’t have to…
When I speak with people who have mocked a lot and then stopped mocking everybody says they stopped mocking because the code got difficult to refactor because so much of the implementation had to be coded into the mocks making refactoring a pain. Refactoring is one of the most important steps in the TDD cycle so if you make that difficult I would say you’re doing something wrong.
But mocks are not all evil. They are great for protocol testing where you want to verify a certain protocol. Mocks also encourage the “tell, don’t ask“-principle which is great.
So should we be mocking? Well, I think a good developer should use the best tools available and there are times when mocking is the best option. But mocks are also very powerful and as they said in one of the Spider-man movies: “With great powers comes great responsibility“. Personally I believe that everybody who learns BDD/TDD will look at documentation and tools and eventually find mocks. They will try mocks and mocking frameworks typically teach mocking in their tutorials so these BDD/TDD novices will start mocking. And they will probably mock more than is healthy for them ending up with code that is hard to refactor and they will think that BDD/TDD sucks. With that in mind I think we who want to convince more people to use BDD/TDD maybe would benefit from not pushing so hard for mocking. We should probably just mention them and explain the pros and cons. And probably encourage people to try BDD/TDD without mocking first and then add mocking as a powerful tool once they mastered the basics.