We got into a bit of a debate at work recently. It went a bit like this:
“Gah! Why do we have this interface when there is only a single implementation?”
(The stock answer to this goes:) “Because we need the interface in order to mock this class in our tests.”
“Oh no you don’t, you can use the FingleWidget [insert appropriate technology of your mocking framework of choice here - e.g. JMock ClassImposteriser]! I’m smarter than you!”
“Well, yes, you can. But if you’ve correctly followed Design for Extension principles, you’ve made the class final, right? And you definitely can’t mock that! Hah! I’m smarter than you!”
“Ah ha! But you could always use the JDave Unfinaliser Agent! I’m so smart it hurts!”
Hmmm… So this is where we are. Is this good or bad? My view on this is:
- You’re no longer testing the code as it will go into production. I mean, you’re not really going to run the production system with this agent enabled, right? If nothing else, it’s going to remove some useful hints to the hotspot optimiser.
- It’s hard to run the tests in your IDE. Well, to be fair, it’s hard in Eclipse because it doesn’t have a default run configuration. You can kind of hack it by adding the appropriate switches to the JDK definition, but that’s definitely in the category of smelly things. IntelliJ is better in this respect – you can at least set defaults for auto-created run configurations.
So, what’s the answer? I really don’t know. I’m on the fence about this one. I hate having interfaces with a single implementation. But I also hate having to remove final from classes that have no business being extended just so I can mock the class in my tests.