aspose file tools*
The moose likes Testing and the fly likes How to test singleton creation with JUnit Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » Testing
Bookmark "How to test singleton creation with JUnit" Watch "How to test singleton creation with JUnit" New topic
Author

How to test singleton creation with JUnit

Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
How to test singleton creation with JUnit. Singleton like this:



The problem is once created it can not be destroyed...

Vladas
Juan Rolando Prieur-Reza
Ranch Hand

Joined: Jun 20, 2003
Posts: 236
Originally posted by Vladas Razas:
How to test singleton creation with JUnit....


My suggestion can be called the "Testable One-Shot Design Pattern."
Change your private attributes to protected.
Then, create a test class that subclasses your Singleton.
Finally, be creative: add a reset method in your new test class, or whatever
you think your JUnit test wants to test in your Singleton (e.g. other attributes, methods peculiar to your singleton, finalization, etc).

I believe this is consistent with JUnit practices.

By the way, the difficulty of testing "one-shot" flip-flop devices is also a recognized difficulty in digital circuit testing.


Juan Rolando Prieur-Reza, M.S., LSSBB, SCEA, SCBCD, SCWCD, SCJP/1.6, IBM OOAD, SCSA
Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
Sounds great. Just one thing "change your private attributes to protected". This means JUnit test affects my code. Well anyway, probably that's the best solution. Have to pay for everything

Thanks!
Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
Bumped into the problem. If I make methods protected and test derrived class, then getInstance() returns object of parent type. I can't invoke reset() on it.
Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
Ok circumvented problem by adding newInstance which is overriden by child class.
J. B. Rainsberger
author
Ranch Hand

Joined: Aug 05, 2004
Posts: 87
http://www-106.ibm.com/developerworks/webservices/library/co-single.html


Author of <a href="http://www.amazon.com/exec/obidos/ASIN/1932394230/ref=jranch-20" target="_blank" rel="nofollow">JUnit Recipes: Practical Methods for Programmer Testing</a>
Juan Rolando Prieur-Reza
Ranch Hand

Joined: Jun 20, 2003
Posts: 236
Originally posted by Vladas Razas:
Ok circumvented problem by adding newInstance which is overriden by child class.


I'm glad this worked for your class under test.

Its "ok" to adjust your target code to address its testability.
"You usually have to refactor your code under test to make it unit-testable...," says V. Massol in JUnit in Action, p69.
[ August 11, 2004: Message edited by: john prieur ]
Juan Rolando Prieur-Reza
Ranch Hand

Joined: Jun 20, 2003
Posts: 236


J.B.,

In your article you say, "Coupling among classes is vastly increased when classes know where to get instances of their collaborators."
Misuse of the Singleton does not mean there is something wrong with the Singleton design pattern, nor its testability characteristics (which is not the focus of that pattern's Problem or Context).

I'm looking forward to your book, though!
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Originally posted by john prieur:
Misuse of the Singleton does not mean there is something wrong with the Singleton design pattern, nor its testability characteristics (which is not the focus of that pattern's Problem or Context).

And nowhere is J.B. implying that there would be something wrong with the Singleton pattern.


Author of Test Driven (2007) and Effective Unit Testing (2013) [Blog] [HowToAskQuestionsOnJavaRanch]
J. B. Rainsberger
author
Ranch Hand

Joined: Aug 05, 2004
Posts: 87
You're right: it's not Singleton's fault that so many programmers apply the problem in a dubious manner. Nevertheless, many programmers apply the problem in a dubious manner; therefore, if you're about to use Singleton, it is important to understand the alternatives.
J. B. Rainsberger
author
Ranch Hand

Joined: Aug 05, 2004
Posts: 87
Incidentally, _JUnit Recipes_ has a recipe for testing object factories, and a Singleton is a special kind of object factory. See chapter 17.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by john prieur:
In your article you say, "Coupling among classes is vastly increased when classes know where to get instances of their collaborators."
Misuse of the Singleton does not mean there is something wrong with the Singleton design pattern


Well, on the other hand, one of the two intentions of the pattern *is* to provide a global access point to the single instance. So it seems fair to say that its intention *is* to let at least some classes know where to get the instance - and therefore to say that the pattern increases coupling.

Or so it seems to me...


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30929
    
158

Note that it isn't necessary to subclass the singleton. If you make the field package-private or protected, other classes in the package can access it. I prefer package-private because someone can't later subclass your class and mess around with it. Usually all the code in a package is written by your team and you can control that people won't take advantage of the package-private access. Once the field access is relaxed the junit test can just set the field to null.

For situations where it is conceivable to want to null out the singleton, I agree it is good to create a method. We do this in our cache classes. We create a public method deleteCache() to clear the cache. That way it is possible to clear the cache from a webpage.


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
By the way, wouldn't

be enough of a test for the singleton behaviour?
Surasak Leenapongpanit
Ranch Hand

Joined: May 10, 2002
Posts: 341
Simply Singleton - Navigate the deceptively simple Singleton pattern .
Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
Honestly I wrote not exactly a sigleton. I wrote class which has create(Object myparam) and getInstance(). Otherwise it's singleton. I've read "Elements of Reusable Object-Oriented Software" about Singletons. Indeed they say singletons are hard to subclass. All solutions in that book where too heavy (unless you really want to derrive from singleton) or not nice (like parent knows all possible children types).

For my simple purpose I found that easiest way is to make reset() function in singleton itself so I can unit test it's "singletonability" (I know there is no such word in english).

I am looking forward for your book too!
Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
Also maybe there is a way to make JUnit start test as it where another application. I mean execute test in clean and fresh application context. Probably that would require restarting JVM and would be slow but you could specify only selected tests that need this feature.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Vladas Razas:
Also maybe there is a way to make JUnit start test as it where another application. I mean execute test in clean and fresh application context. Probably that would require restarting JVM and would be slow but you could specify only selected tests that need this feature.


It would probably suffice to use a fresh ClassLoader, but I would seriously question wether it'd be worth the effort...
Juan Rolando Prieur-Reza
Ranch Hand

Joined: Jun 20, 2003
Posts: 236
Originally posted by Lasse Koskela:
By the way, wouldn't

be enough of a test for the singleton behaviour?


Sure, if the uniqueness of your Class is the only feature of the Class worth testing. But, Singletons can have lots of methods and attributes, and they should be tested as well.

And to Jeanne B., true you don't have to use the subclassing pattern of testing to test the Singleton. But I like it, and I like to use a uniform testing strategy. The other suggestion of using package visibility is fine, although it grants much more visibility to other Classes than you really intended, whereas protected visibility is the minimum breach of your intention just to support testing.

Happy Coding
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Originally posted by Lasse Koskela:
By the way, wouldn't

be enough of a test for the singleton behaviour?

Originally posted by john prieur:
Sure, if the uniqueness of your Class is the only feature of the Class worth testing. But, Singletons can have lots of methods and attributes, and they should be tested as well.

Of course. But testing those methods is no longer related to the object being a singleton, is it? The test I wrote above should be enough to test that the class has one and only one instance of it. Testing whether the methods in that one instance behave as they're expected to is no different from testing whether the methods of a non-singleton class behave as they're expected.
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30929
    
158

Also maybe there is a way to make JUnit start test as it where another application. I mean execute test in clean and fresh application context. Probably that would require restarting JVM and would be slow but you could specify only selected tests that need this feature.

Vladas,
If you run the tests through the <junit> task in ant and set the fork attribute, you get this functionality. It isn't too slow (although it is slower than just running test test.)

The big problem I see is that we get a command line window flashing on the screen for each and every test. If you are trying to work, this is annoying. If the tests run on a separate machine it isn't a drawback. But then, neither is speed.

subclassing pattern of testing to test the Singleton. But I like it, and I like to use a uniform testing strategy.

John,
As you can see in my thread, I don't really like subclassing to test if it isn't necessary. But if that is your strategy, I understand.
[ August 12, 2004: Message edited by: Jeanne Boyarsky ]
Juan Rolando Prieur-Reza
Ranch Hand

Joined: Jun 20, 2003
Posts: 236
Originally posted by Jeanne Boyarsky:
...
John,
As you can see in my thread, I don't really like subclassing to test if it isn't necessary. But if that is your strategy, I understand. ...

[ August 12, 2004: Message edited by: Jeanne Boyarsky ]


Thanks!
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: How to test singleton creation with JUnit