aspose file tools*
The moose likes Testing and the fly likes Passing objects that persist data as mock Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » Testing
Bookmark "Passing objects that persist data as mock" Watch "Passing objects that persist data as mock" New topic
Author

Passing objects that persist data as mock

Soheil Tayari
Greenhorn

Joined: Apr 04, 2008
Posts: 29
Ok I start off by explaining the issue in my code. I'm new to JUnit and I've started to test my application. From design point of view I have a Factory class which returns DAO objects. Service layer classes use this factory class -which is a singleton- to access the DAO objects they need. If I want to mock these DAOs and let the classes under test use them there's no way to pass them these mocks. Each class in service layer uses a syntax like:

to get it's DAO. I can change the code so the calling class could pass the DAO but I don't think that's a good thing to do cuz It could go all the way up the calling chain and when you get to testing those classes you face the same problem. I would appreciate a good solution for this.
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30537
    
150

Soheil,
What about DAOFactory.getInstance(). Can you make it so this returns the mock dao? Or call this method in the constructor of your service layer so you can overwrite it in the test.


[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
Soheil Tayari
Greenhorn

Joined: Apr 04, 2008
Posts: 29
Jeanne Boyarsky wrote:Soheil,
What about DAOFactory.getInstance(). Can you make it so this returns the mock dao? Or call this method in the constructor of your service layer so you can overwrite it in the test.

Actually I made the DAOFactory constructor protected instead of private so I can extend it and override the methods to return mock DAOs. The problem is I don't know how to tell the method under test to use this mock-returning factory instead of the real one. I could pass the factory to method but I don't think that's a good idea.
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30537
    
150

Soheil,
One approach is:

Soheil Tayari
Greenhorn

Joined: Apr 04, 2008
Posts: 29
Thanks for the reply Jeanne. Actually my problem is solved and it's similar to what you have suggested. I share what I learned so others with same problem could use it too.
I referred to some good sources for solving this problem. One is Manning JUnit Recipes sections 2.11 and 14.4 which very clearly addressed the exact same problem of testing singletons and objects created in another method. In my case what I did was to give my service class 2 constructors like:


So the class can access both the singleton DAOFactory and any subclass of DAOFactory. Then I made the DAOFactory constructor protected (which is private enough) to e able to subclass it. In the extended DAOFactory I overrode the methods returning DAOs to return mock DAOs. Now from my test I create and pass extended factory to UserManager and it will retrieve it's DAOs from it's factory without knowing the difference. At least that solved my problem .

Also another good article is: Unit testing with mock objects
Lorand Komaromi
Ranch Hand

Joined: Oct 08, 2009
Posts: 276
How about making DAOFactory an Abstract Factory and using some DI framework to inject the implementation..? You could get rid of the no-rg constructor and you'd have one less case to test (instantiating the class using the no-arg constructor)!


OCJP 6 (93%)
Soheil Tayari
Greenhorn

Joined: Apr 04, 2008
Posts: 29
Lorand Komaromi wrote:How about making DAOFactory an Abstract Factory and using some DI framework to inject the implementation..? You could get rid of the no-rg constructor and you'd have one less case to test (instantiating the class using the no-arg constructor)!

That's probably a good solution. But since I'm not quite familiar with dependency injection I'm looking for an alternative. For now that solved my problem.
 
 
subject: Passing objects that persist data as mock