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 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.
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 .
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%)
Joined: Apr 04, 2008
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.