10
votes

When a class implements an interface, then it is easy to mock, but, you have to create an interface for it.

You can also mock by subclassing and overriding. If your base class provides a parameterless protected constructor, then your subclass mocks are not tied to changes in the base class constructor.

At first glance, it seems like the subclassing method to creating mocks is more desirable than creating interfaces for everything, but obviously, that's not how most people are doing it.

So, why are mocks based on interfaces considered a better practice than mocks based on subclassing?

2
Strange question to be asking in 2015, as every mocking library has had first-class support for mocking classes for many years now. And, as far as I know and at least in the Java community, only one of the jMock developers actually encouraged users to mock only interfaces; other Java mocking tool developers did not insist on that. - Rogério
I don't think it's strange if you're not using a mocking library. That being said, I would definitely favor using a library to mock concrete classes than having to create interfaces just for the sake of testing. - jmrah

2 Answers

6
votes

Contrary to most beliefs, even if you do Test-Driven Development (TDD), you should still follow good design practices. The trick is to make APIs testable and well-designed. TDD isn't a design methodology, but a feedback technique.

Therefore, it's not a question of Interface Mocks versus Subclass Mocks, but rather a question of interfaces versus subclasses.

That's a really old discussion that ought to have been over back in 1994; in Design Patterns, we learn that we should favour composition over inheritance.

There's a long discussion about this topic, but in short, in languages with single inheritance, basing an API design on inheritance is to constrain all future variability along other (yet unforeseen) dimensions. Inheritance in such languages is simply too restrictive. Since all major Object-Oriented languages (Java, C#, Ruby) have single inheritance, you ought to see most Object-Oriented code bases correctly avoiding inheritance.

When a design is based on composition over inheritance, it follows that if you use mock objects, you'll be mocking interfaces, not base classes.

3
votes

When you subtype and override, you have the risk of missing overriding one of the methods you should have overridden, and actually running the "production" code, which you'd want to isolate away from your test.

When you mock an interface, 100% of its behavior must be mocked. Whatever isn't explicitly stated by mocking will just throw an exception, and force you address it.