Have you ever stumbled across a C# masterpiece where every single class is adorned with its very own one-liner interface? Something like:
public interface IDoSomething
{
void Do();
}
public class DoSomething : IDoSomething
{
public void Do() { /* Magic happens here */ }
}
And when you ask why—the response is invariably:
"It's for testing purposes."
Oh, really? Testing? That's your reason? Let’s unpack this nonsense.
Interfaces Are Not the Swiss Army Knife of Testing
If your interface exists solely to mock a single class that has exactly one implementation, in the same project, congratulations, you’ve just achieved the pinnacle of overengineering while solving exactly zero problems.
Mocking for tests? Delegates exist. Base classes exist. Heck, even just passing a lambda can solve this epic challenge. Why make an entire interface for something that only has one possible implementation? The "flexibility" argument collapses faster than my patience when reviewing this kind of code.
Misunderstanding the Role of Interfaces
Interfaces are for abstraction and defining communication between unrelated components. They shine in polymorphism, dependency inversion, and cross-domain communication. They are not a participation trophy for every single class in your project.
Using interfaces this way is like buying a Ferrari to drive to the corner store—it’s excessive, wasteful, and makes people wonder what went wrong in your design thinking.
But Testing Is Important, Right?
Yes, amigo. Testing is important. But abusing interfaces is like solving a math problem by adding more numbers until it looks right.
Do this instead:
Delegates: Pass a
Func
orAction
to your method and test your logic without redefining the universe.Base Classes: If you really, really need some shared behavior, consider inheritance. But I warned you!
Fakes/Stubs: Use a plain old object. Shocking, I know!
Static Methods: It’s 2025; static methods won’t set your IDE on fire.
Don't Create Interfaces Just Because You Can
The next time someone says, "I need an interface for testing," ask them if they’ve ever met a delegate. And if they respond, "But what if I need to swap the implementation in the future?"—tell them to call you when they actually have two implementations.
Until then, please stop writing interfaces that only exist to inflate your codebase. Your teammates, your future self, and the .NET community at large will thank you.