Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

Wicked Cool Jobs

Syndication

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
Static methods can be a cool solution to many issues and they're definitely convenient. I routinely use static methods in place of specialized constructor functions. Sometimes it is absolutely necessary to maintain state between method calls or across threads and static methods are a logical choice. However, sometimes static methods do not mix well with Test Driven Development. A direct reference to a static method from one class to a second class means that the first class is strongly coupled to everything that the second class uses. Keeping any kind of state in static members can also interfere with your unit tests (more on that here). Always be cognizant of this fact before you create a static method.

Just to get this one out of the way, you cannot mock (or stub) a static method, period. Crying or wailing about it won't help. There is no easy way to substitute in a stubbed implementation for a static method. For that reason alone, I advise developers to never do anything in a static method that calls out of the current AppDomain (HttpContext objects, database calls, MSMQ manipulation, etc.). Even if you need to use a static (or thread local storage or HttpContext storage) field to maintain state, all consumers should access this cached state through some type of abstraction interface for easier testing.

Besides the testability issue, do you really want your application strongly bound to a particular implementation like MSMQ? If you limit the coupling to MSMQ, you can more easily substitute in MQSeries or a call into your company's new utopian Enterprise Service Bus later. My point merely being that designing to maximize testability often happily coincides with just plain good design or architecture.

Singletons

Singletons always, always, always interfere with writing decoupled and isolated unit tests. There is a lot of interest in Domain Driven Design right now and one of the key concepts in DDD is that often the domain objects are retrieved or persisted through a repository that manages caching and persistence for a domain class or small family of classes. The repository is stateful across requests or classes, so it is a natural candidate for a singleton. Don't be seduced by the dark side. If you make the repository a singleton, all of the consumers of the repository (and there will be a bunch) cannot be tested in isolation. You can do something to allow you to mock or stub out the underlying data source classes, but take it from me, this sucks (hard). Your unit tests are dependent upon the implementation of the repository class. This makes your unit tests harder to write because there is more code, and harder to understand because you are investing more of the unit test in setting up the internal state of the repository than exercising the consuming class. For a multitude of reasons, it is always important to make your unit tests intention revealing. Mocking the guts of the repository may end up obfuscating the real intention of a unit test.

Here's an article I wrote on a TDD-friendly alternative on the StructureMap site for exactly this situation with more discussion on the issue: http://structuremap.sourceforge.net/SingletonInjection.htm.

You should also check out Robert Martin's article Singleton vs. Just Create One. While you're on the ObjectMentor site, read everything those guys write, it's all good stuff.

As an aside, one of my friends does a lot of technical interviews for .Net developers for a very large employer in Austin. His weedout question is "what is the difference between a static and an instance method?" He is continually scratching his head on the percentage of people who wash out on this question. I have no idea what to say about that.

Posted Wed, Jul 20 2005 5:02 PM by Jeremy D. Miller
Filed under:

[Advertisement]

Comments

Jeremy D. Miller -- The Shade Tree Developer wrote TDD Design Starter Kit
on Thu, Jul 21 2005 1:05 PM
Here's a handful of articles on designing with or for TDD I had originally posted on my...
James Shaw wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Thu, Jul 21 2005 2:37 PM
"Sometimes it is absolutely necessary to maintain state between method calls or across threads and static *methods* are a logical choice"

Don't you mean static *members*? Static methods have nothing to do with state..
Jeremy D. Miller -- The Shade Tree Developer wrote Chill out on the Singleton Fetish
on Thu, Aug 4 2005 2:57 PM
My little team is taking over development for one of our other products.  Today is the first...
Jeremy D. Miller -- The Shade Tree Developer wrote Chill out on the Singleton Fetish
on Thu, Aug 4 2005 3:01 PM
My little team is taking over development for one of our other products.  Today is the first...
Jeremy D. Miller -- The Shade Tree Developer wrote Best and Worst Practices for Mock Objects
on Tue, Jan 10 2006 6:01 PM
Mock objects are like any other tool.  Used one way they’re a huge time saver.  In other cases...
jokiz wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Fri, May 26 2006 12:18 PM
i'm starting out with unit testing and this isue on static methods and singleton has started to bite me.  thanks a lot for this post sir!
Jeremy D. Miller -- The Shade Tree Developer wrote Best of the Shade Tree Developer (with actual links!)
on Mon, Aug 7 2006 4:51 PM
Between being extremely short handed at work, tech' reviewing a new book, a
possible book proposal...
Taylor wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Sun, Oct 21 2007 2:17 PM

I'm late to the party, but regardless I disagree with the assertion that "you cannot mock (or stub) a static method, period".  Check out my article about it:

taylorbarstow.com/.../unit-testing-with-static-classes-and-singletons

Taylor

Jeremy D. Miller wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Sun, Oct 21 2007 7:15 PM

Taylor,

This post was written before TypeMock.

Jim Showalter wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Mon, Dec 22 2008 3:01 PM

In Java, static methods are easily mocked using JMockIt (it's trivial). Are you saying there is no equivalent to this for .NET?

Jeremy D. Miller wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Mon, Dec 22 2008 4:03 PM

@Jim,

This is an OLD blog post.  You can use TypeMock for that today.  And just for fun, google "TypeMock, statics" and just watch the controversy spill out.

Yes, you can mock a static method, but should you?

Jeremy D. Miller -- The Shade Tree Developer wrote It’s been years since I’ve gone on an Anti-Singleton rant
on Tue, Jan 6 2009 4:52 PM

So apparently it’s time again: See: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful

Community Blogs wrote It’s been years since I’ve gone on an Anti-Singleton rant
on Tue, Jan 6 2009 7:16 PM

So apparently it’s time again: See: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful

Dave wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Thu, Jan 8 2009 3:45 AM

Does this apply to extension methods, since they are static methods?

wolf++ » TuneWiz Loosely Coupled, Easily Testable wrote wolf++ » TuneWiz Loosely Coupled, Easily Testable
on Tue, Jan 13 2009 3:30 AM

Pingback from  wolf++ » TuneWiz Loosely Coupled, Easily Testable

DotNetKicks.com wrote TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Thu, Feb 19 2009 9:49 PM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

yakumoklesk wrote re: TDD Design Starter Kit - Static Methods and Singletons May Be Harmful
on Wed, Oct 28 2009 5:43 AM

I just have a question. Does this also apply to Factory pattern? Factory pattern has static methods, but those methods creates new instances, so it would act just as a new instantiator rather than a regular static method.

Thanks.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us