Friday, 18 March 2011

Stop mocking me!

The last couple of days there's been some discussion about mocking frameworks. Is mockito better than easymock? I don't care. Use whatever tool you need to or that you are most familiar with. Add tools to your toolbox of solutions.

The bigger discussion came about if we should mocking everything. My experience is that I've been burned by mocks hiding the actual behaviour of a component via it's dependencies. I've had what I call "integration tests" - junit tests that use most of the app's code and talk to a db ultimately - uncover bugs in the underlying dao's. Because of those experiences I'm not a fan of mocking everything. Mocking has it's place, but I've found those to be rare. For example, if you wanted to simulate an "impossible" condition in your code, or if you're want to simulate a scheduled task, I've used mocking there.

One of the biggest strengths about mocking is that you're testing your class / module in isolation. I think that one of the biggest weaknesses is that you're testing your class / module in isolation. You still need to test the components connected. You still have to make sure that when you give valid inputs at the top, it's not going to blow up at the bottom. I can hear people saying that "that's were your integration tests come in". Sure, but I like a quick "is everything working" without deploying it to containers or dealing with data leaking between tests.

Another thing that I don't like about mocking is that it tends to turn the code under test inside out. I have to know what services it will call, what it will pass in, what's going to be returned from those services, etc. I'd prefer that my unit tests are testing the public interface of the class. Yes, it's really white-box testing, but I only really care that the class is doing what it says it's doing. I don't care exactly how it's doing it. Do I care that the class calls or private method or an external service to get a job done? Hint: the answer starts with a "na" and ends with "uh".

Short answer: use mocks where it makes sense, but favour "real" code from the app where you can.

1 comment: