views:

121

answers:

6

I've read cases for and against using the singleton pattern. One common case against describes the difficulties in unit testing with singletons, but I'm unclear as to why this is? If the unit test is part of the build couldn't you just reference the singleton and use it when its needed? (I'm thinking from a java perspective but I guess it shouldnt matter)

+7  A: 

A great article about this is Singletons are Pathological Liars. This describes, using a simple example, why testing using singletons is unexpectedly hard.

Greg Hewgill
The link is broken.
Emil
Works fine here.
Björn
Great article, +1. The only thing I would like the article to change is the end example... to me it makes more sense for the charge() method to be on the CreditCardProcessor and have it take the card and the amount as parameters :)
rmeador
A: 

This Google Techtalk does a pretty good job of describing the problems with singletons and global state when it comes to unit testing.

Martin Törnwall
A: 

I don't recall ever reading that, but I suspect the problem is the fact that you can only create one. In some cases, that may not be a problem, just test it normally.

But what if you want to create and test a different one, perhaps with different constructor/factory method parameters? Do you restart the JVM? Or create your singleton so that it's not really a singleton and can be reset? Not good.

Rodney Gitzel
+2  A: 

If you reference a singleton class that exists outside of the class under test, then you no longer have a true unit test. Instead of testing a single unit - the target class - you're now testing two units - the target class and the singleton.

There's also the fact that singleton objects tend to have state. For unit tests to be repeatable, those state changes need to be rolled back when the unit test is complete. Alternatively, you have to create a mock version of the singleton that's destroyed after each test is run. Either adds a fair amount of overhead, both in source code and in running time.

quanticle
+1  A: 

Because the singleton is an OOPish global variable. Basically, all functions relying on the use of the singleton (directly or indirectly) are not guaranteed to be deterministic (i.e. you cannot expect the function to return the same outputs for the same inputs T each and every run).

André Caron
+1  A: 

Singletons are a problem for several reasons:

  • They're a special case of a Service Locator, which provides a mechanism to "get me one of those" that isn't necessarily easy to override when needed.
  • They provide an entry point to read or write global variables. Wrapping those global variables up in an object with only one instance that is globally accessible via the Singleton pattern doesn't magically make them stop being global variables.
  • They're trouble for maintenance too. For example, what happens when they stop being a true Singleton -- maybe you have to access two databases instead of "the database"?
Jeffrey Hantin