Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are single implementer interfaces for unit testing an antipattern?

In regards to unit testing, I was taught that production code shouldn't have test-related code in it.

Well, I feel like I'm breaking that rule every time I try to unit test.

I have a class internal to my assembly, Xyzzy. I want to dependency inject it into another class and then stub it so I can test that the other class in isolation, so I make an interface, IXyzzy. Oops, now I have code in production that's really only there for test. Even worse, I've kind of gone against what interface is (describes what an implementer can do, not what it is). Xyzzy's public interface and IXyzzy are exactly the same and no one else (except the stubs) implements IXyzzy.

That seems like a bad thing to me.

I could create an abstract base class or make all the public methods I want to test on Xyzzy Overridable/virtual, but that feels wrong too since Xyzzy isn't designed for inheritance and from a YAGNI perspective, won't ever be inherited from.

Is creating single-implementer interfaces solely for the purpose of testing an anti-pattern? Are there better alternatives?

like image 672
Jeff B Avatar asked Feb 20 '13 23:02

Jeff B


People also ask

Is mocking an Antipattern?

The mockery is one of the most popular anti pattern across developers, as it seems that everyone has had some experience mocking code to test. The first idea, Mocking is simple: avoid external code to focus on what you want to test.

What is single unit testing?

Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.

How interface is useful in unit testing?

When you have an interface, you can easily “hide” any implementation behind it, even a mock for a unit test. An important subject of unit testing is managing external dependencies. The tests should directly cover the unit while using fake replacements (mocks) for the dependencies.

What is unit testing implementation?

In computer programming, unit testing is a software testing method by which individual units of source code—sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures—are tested to determine whether they are fit for use.


1 Answers

Yes, it is an anti-pattern. A pattern would be "a solution to a common problem in a certain context". But in this case, what we have is a work-around, not a solution.

The problem in question is the need to isolate a unit to be tested from (some of) its dependencies, so that the implementation of those dependencies doesn't have to be considered when writing the unit tests. The general and true solution to this problem is called "mocking", where the test writer can specify whatever behavior is needed from the mocked dependencies.

In contrast, forcing the developer to create unnecessary separate interfaces, or declare methods as virtual, is only a work-around for the technical inability to cleanly isolate a unit from others.

For .NET, there are several mocking tools that provide this isolation ability, namely TypeMock Isolator, JustMock, and MS Fakes. Other languages/platforms (including Java, Ruby, and Python) have their own tools of similar expressive power.

like image 152
Rogério Avatar answered Oct 10 '22 02:10

Rogério