Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to test singleton creation with JUnit

 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok circumvented problem by adding newInstance which is overriden by child class.
 
J. B. Rainsberger
author
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
http://www-106.ibm.com/developerworks/webservices/library/co-single.html
 
Juan Rolando Prieur-Reza
Ranch Hand
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


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
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
J. B. Rainsberger
author
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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...
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34378
346
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Lasse Koskela
author
Sheriff
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way, wouldn't

be enough of a test for the singleton behaviour?
 
Surasak Leenapongpanit
Ranch Hand
Posts: 341
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 11962
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 34378
346
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic