Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Junit testing for singleton class

 
Gurpreet Sidhu
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have one class having private constructor. Can any one suggest how to write junit methods for methods of that particular class. How to call the methods of that class as we can't create the object?
 
Lasse Koskela
author
Sheriff
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How does the production code make use of that class?
 
Gurpreet Sidhu
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
got it ....first creating instance of object and returning it through public method
 
Timothy Frey
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Trying to write unit tests for singletons can be very difficult, which is one of the reasons some people try to stay away from them. Unit tests are designed to be independent, but because you are stuck with exactly 1 instance of an object, all of your tests become tied together. Methods called on the singleton may have side effects that alter the state of the object and will affect method calls in the future.

I'm not sure what you meant by your last response; sounds like you're either accessing the singleton normally or you went ahead and allowed new instances of the object to be created only for testing purposes. I can't think of a way to test singletons without having methods that are there explicitly for testing purposes. For example, you can have a reset() method that will return the object to its original state. You can call reset() to ensure that each test is independent.

There are tons of articles out there weighing the pros and cons of the Singleton design pattern. If you can, it might be worthwhile to think about getting rid of the singleton and just creating 1 object.
 
Lasse Koskela
author
Sheriff
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The main documented reasons for using the Singleton pattern are to ensure that a class only has one instance running around in the system and that there's a global point of access to it for whichever part of the system needs to access it.

One problem I see with Singleton is that it's solving the wrong problems.

Rather than "protect" ourselves from having multiple instances by using the Singleton pattern, we should just create one and make sure our architecture lets us do that in a simple, reliable way.

Rather than providing a global point of access for anyone who might need it, we should turn the table around and only provide the access to those who do need it, effectively making explicit the dependencies between parts of the system. Introducing dependency injection is great for doing just that.

The other problem I see with Singleton is its negative impact on testability (and immobility among other things). Mainly, however, it's not about not being able to test the singleton object's behavior but about not being able to test other objects' behavior that depend on the singleton because the singleton has state that makes those tests non-deterministic, brittle or simply sloooow to execute. All it takes is for the singleton to access some configuration file, touch the network, or make some other kind of assumptions about the environment it's running in.
 
Pradeep bhatt
Ranch Hand
Posts: 8927
Firefox Browser Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In case of Junit, Is is ok to use junitx PrivateAccessor.setField() to reset the singleton field to null so that a new copy is created ? That is how I test it. Is is recommended ?
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Lasse Koskela:

One problem I see with Singleton is that it's solving the wrong problems.


And even when it's solving the wrong problem, it is probably solving it in the wrong place. Even if it really is appropriate to ensure that there will be only one instance in the system, and that it will be globally accessible, the code doing it should probably reside in a different class, as it is a different responsibility than the one the "Singleton" class actually has.
 
Lasse Koskela
author
Sheriff
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Prad Dip:
Is it ok to use junitx PrivateAccessor.setField() to reset the singleton field to null so that a new copy is created? That is how I test it. Is it recommended ?

Well, considering that I've considered most Singletons I've seen unnecessary, my first recommendation without knowing more about the context would be a refactoring called Replace Singleton With Just Create One.

Having said that, if the Singleton has state that affects its externally visible behavior during test execution, yes, resetting the Singleton field could be an alternative path of action if changing the production code doesn't feel right at this time.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic