Mocking Should Not Require Interfaces

Exploring the ecosystem outside Perl, I have found multiple examples of languages and frameworks that require you to implement your classes as an interface + an underlying engine class when you want to mock that class during testing. This is all fine and dandy if the interface can be used as part of multiple classes. However, if the only reason you have an interface is so you can mock this class during testing, then I would call that a language-runtime smell.

If you are never going to use the interface for anything other than mocking, then you are violating both DRY (Don't Repeat Yourself) and YAGNI (You Ain't Gonna Need It). Using interfaces requires synchronizing method signatures between the interface and its classes, thereby violating DRY. If the interface is only used for mocking that class, your are violating YAGNI. DRY and YAGNI reduce your code complexity, making it easier for you to understand your code later (and you always have to understand your code later).

It is said that you don't really know a tool until you know at least 3 ways to abuse it - forcing mocking to occur only when you use an interface has to be one of the ways to abuse interfaces. (Extra points to those who point out other examples of interface abuse.) I used to wonder why so much of Java code I looked at required interfaces that were never re-used - now I know.

1 Comment

I'm not sure I understand the first paragraph, but I've met Perl unit tests that were passing despite the fact the mocked classes changed their APIs. If the classes had provided their behaviour in a way, the mockes would have failed and the problems would've been fixed.

Leave a comment

About Mark Leighton Fisher

user-pic Perl/CPAN user since 1992.