Unit testing Hibernate POJO
I have a hibernate POJO that I want to unit test. It looks similar to this:
public class MyPojo{
private final Integer someIntData;
private MyPojo(){
//Just to sa开发者_StackOverflowtisfy compiler, hibernate will override
someIntData = null;
}
//Methods etc...
}
I'd like to unit test this class, but don't really want to make a new constructor just to set 'someIntData' manually. Is there a quick and easy way to get hibernate to instantiate a test instance of MyPojo without mucking around with a mock database?
Private constructor means that you are either providing a "builder" method to replace the constructor (usually for immutable instances) or that the class is never meant to be initialized at all. In the later case, its usually because the class is meant to be a singleton and you'd provide a method which returns the single instance.
Hibernate does not complain about it because it uses reflection to consume this constructor. As you are not supposed to provide special code for a test, the only solution I see is to use reflection to instantiate a new POJO.
But I really think you should reconsider and provide a builder method, accepting the parameters needed to build a new instance.
What I'm going to suggest is ugly, but I think the best approach is not to use hibernate for the unit test, and use reflection to instantiate the object (which is what hibernate does internally). For example
Constructor[] cons = MyPojo.class.getDeclaredConstructors();
// Change the accessible property of the constructor.
cons[0].setAccessible(true);
MyPojo secret = (MyPojo)cons[0].newInstance(null);
Code taken from http://dunwood.blogspot.com/2004/05/instantiate-java-class-that-has.html
I remember reading that there are some frameworks that make using reflection easier for unit-tests, but I've never used them. In this type of cases, I always prefer to create a second constructor or to make the constructor package protected.
If it's a real unit test, you shouldn't need to depend on Hibernate.
It's common to change the visibility of methods, or even introduce some in order to be able to unit test a class. I wouldn't mind having a public constructor with an Integer as argument in order to unit test the POJO.
You'll certainly need to be able to set the ID in your POJOs when you'll test services anyway. For example, if you want to test that myService(MyPOJO p)
calls myDAO.findFoos(p.getId())
, you'll need an ID in your POJO.
精彩评论