aspose file tools*
The moose likes Testing and the fly likes JMock with singleton object Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » Testing
Bookmark "JMock with singleton object" Watch "JMock with singleton object" New topic
Author

JMock with singleton object

Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Hello Friends
Is it possible to create a mock object of an singleton object defined as below.

protected static CompleteCase instance = new CompleteCase();
private CompleteCase() {
};

Please help I need to stub this class.

Thanks
Farouk


SCJP, SCWCD, SCBCD, SCEA 5
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
In your test, you can create a subclass of that class, which is then allowed to assign the protected static field a mock implementation.

That's a rather ugly solution, though, and a big hint to the fact that the design is far from optimal. If I were you, I'd work hard on not having to do that.


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
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Hi thanks for ur reply. Please can you give an code example of the extended sub class of the singleton class.

Thanks
Farouk
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Any ideas or examples of JMOCKING singletons plz
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30757
    
156

Farouk,
If you must do this, I prefer to put the test in the same package as the code, rather than subclassing.

Then the test can just call:
myObjectThatICannotRefactor.instance = mockCompleteCase;


[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
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Jeanne thanks for your reply. I am having the test in the same package of the classundertest.

Mock warehouse = new Mock(Warehouse.class);

Assuming Warehouse class is a singleton. Using JMock the above line throws
an exception saying cannot create an instance of mock Warehouse as Warehouse does not have any public constructor. There by making me not able to even proceed from there.
My singleton object does not have state so i dont have any problem running one or many times.

So if i am tesing Classundertest i should mock StaticFacade and Mock CompleteCase

Hope you understand. I am not able to convince team members that JMock is a good option. Hope you can help me...
Thanks In Advance//
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30757
    
156

Mohamed,
We have a similar design. We put a wrapper around the static facade to make it more easily testable. In the long run, this makes things easier.

Now back to your question: cglib allows you to pass arguments to the constructor. The problem comes from when you don't have any public constructors as with a singleton. I'm not positive because I haven't used cglib (I prefer making the code testable), but I think you can't mock something without any public constructors.

So your choice are:
1) use an interface/instance instead of the static facade
2) wrap the call to the singleton and mock that - you can intercept either the static method call (what we do) or the singleton within
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Jeanne
Thanks again please can you help with an example from your code of the wrapper class.
I am trying to test the methods in the singleton class sitting behind a static facade and these singleton classes call third party classes.

A code example will be greatly appreciated
Thanks
Farouk
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Any ideas or examples of JMOCKING singletons plz
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30757
    
156

Mohamed,
I don't have a code example because we don't mock singletons. I think that is the general consensus here. Addtionally, it looks like JMock doesn't support mocking objects that don't have public constructors.

What is the reason you can't refactor the code to make it more testable?
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Hello Jeanne

By refactoring do you mean removing Singleton?

Regards
Farouk
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30757
    
156

Removing it or wrapping it a non-singleton object.
Mohamed Farouk
Ranch Hand

Joined: Jun 08, 2005
Posts: 249
Hello Jeanne
Thanks for your reply, The whole point of using a singleton pattern is to make sure that there is only one instance of this business object available in the client tier their by reducing the object creations.
Now by wrapping this singleton using another non singleton object really defeats the whole purpose of using the singleton.?
Is it coding for testing or coding for object optimization?

To resolve all of this have you seen https://jmockit.dev.java.net/tutorial.html looks like a solutions for all mocking problems. But bad news for me is it not useful as JMockit requires tests to be run under a Java SE 5 VM.

Like to hear your opinion..

Thanks
Farouk
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30757
    
156

The whole point of using a singleton pattern is to make sure that there is only one instance of this business object available in the client tier their by reducing the object creations.

I agree that the point of using a singleton is to make sure there is only one instance of the business object. However, reducing object creations is not necessarily the goal. Creating objects isn't bad in and of itself.

Now by wrapping this singleton using another non singleton object really defeats the whole purpose of using the singleton.?

Depends on your purpose in using the singleton. If it is for caching data or otherwise ensuring a single object, the purpose is intact with a wrapper.

If you can't introduce a wrapper, you could always introduce a constructor for testing. But that seems like a bigger design compromise to me.

Is it coding for testing or coding for object optimization?

"Premature optimization is the root of all evil" - Knuth
Do you have an actual problem with creating too many objects? If not, I wouldn't worry about it at the moment.
Anthony Si
Greenhorn

Joined: Feb 02, 2009
Posts: 2
I tried the following approach to mock a final singleton class and it seems to work:

1) use ClassImposteriser



2) Create Mock singleton class


3) Download JDave http://www.jdave.org/resources.html

4) set unfinalizer in VM argument: -javaagent:C:/to/path/jdave-parent-1.1/lib/jdave-unfinalizer-1.1.jar

5) include asm-3.0.jar from JDave package into build path

Why it works:

step 1) & 2)
Singleton classes has a private variable which stores the instance of singleton object, find out the name of this private variable. Using reflection, set this field with the mock class you just created, hence forcing every subsequent call to point to the mock object instead.

The assumption is that in getInstance() method is doing something like this:


step 3) & 4) & 5)
In my case, the singleton class is final. That's why I used JDave unfinalizer.

I'm using JMock 2 which requires Java 1.5+

Any comments?
Abhishek Sharma
Greenhorn

Joined: Oct 19, 2005
Posts: 2
thanks Anthony.. we were looking for something to enable us mocking a Singleton, and the approach given by you works perfectly...

SCJP 6.0 | SCBCD 5.0
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JMock with singleton object