Unit testing Hibernate POJO - java

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 satisfy 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.

Related

Avoiding Static method for testability when creating a sort of Factory

When refactoring some code I found that I had a new call which created a concrete class.
I was looking for a way to avoid the call to create a concrete class and improve testability so I created a sort of Factory which was responsible for returning me an instance. I then, using Spring constructor injection, inject the factory to the System Under Test.
However now I'm faced with a question about making the method in my factory static while at the same time having good testability. According to Misko Hevery, Static Methods are Death to testability however I do not have a clear idea what to do to remove the call to new, have good unit tests, and avoid the static method call.
This is an extract from the class that uses the factory. I am testing methods in this class that make use of the constructed (and mocked) columnFamilyTemplate:
protected AlertFieldMatcher(ColumnFamilyTemplateBuilder columnFamilyTemplateBuilder, Keyspace keyspace,
T2JsonUtilInterface jsonUtil) {
this.columnFamilyTemplate = columnFamilyTemplateBuilder.build(keyspace, CF_ALERT);
this.jsonUtil = jsonUtil;
}
And this is the factory, which I now have to mock in tests for methods in the SUT (above):
public class DefaultColumnFamilyTemplateBuilder
implements ColumnFamilyTemplateBuilder {
#Override
public ColumnFamilyTemplate<String, String> build(Keyspace keyspace,
String columnFamily) {
ColumnFamilyTemplate<String, String> builtTemplate =
new ThriftColumnFamilyTemplate<String, String>
(keyspace,
columnFamily,
StringSerializer.get(),
StringSerializer.get());
return builtTemplate;
}
...
}
The only option I see is to leave my Factory type object as is, ie not make the method static.
If you're going to remove "new" from your application, you need some mechanism for creating objects on your behalf. There are three mechanisms you might want to check out.
The first is dependency injection. DI containers allow you to take a more interface-based approach and choose what implementations to use at runtime. Spring is the most popular DI container while CDI is the new "standard". DI is fine, but it's not necessarily the kind of thing you want to introduce late in a project.
The second mechanism is the Java ServiceLoader which allows you to change implementation of components by adding and removing files from your classpath. You might find this a bit fiddly.
The last mechanism would be to use a static method (!!!!) that reads in a property which is the class name of your factory object and use Class.forName().newInstance() to create the factory object for you. This might be the simplest approach. It gives you a seam to inject a new mock factory into.
Avoiding statics is a good idea but they have their place. Use them if you understand the trade-offs involved.
You don't need to create explicitly a factory.
Extract the the creation of the new instance to a protected method in your class, exactly the same as if you were creating a factory method but providing new ThriftColumnFamilyTemplate(...) as default implementation.
In your unit tests your sut will be a partially mocked version of the class, mocking the factory method, instead of the real class. With this approach the only code untested will be the factory method, that is one single line. For the partial mocking you can use EasyMock IMockBuilder.

How to mock a function used in the object constructor (with Mockito)?

I need to write unit tests with Java for an Android application. What I currently need to do is to create an object Picture and use it for some tests. The problem with this object is, that it's constructor has a method call:
public Picture(File imageFile) {
this.filename = imageFile.getName();
this.imageDimension = getImageDimension();
/.../
}
Method getImageDimension() references some other classes, therefore I would prefer for separability to just mock it's result. For mocking, I need to give Mockito a constructor, so it seems to me like a chicken-egg problem.
So, is there a chance to mock a function used in the object constructor with Mockito? If no, how could this situation be solved without changing the original code?
Normally you'd mock the entire object and not just a part of it. But if it's not final, create a subclass of Picture and override the constructor and do your custom thing there. That way you can avoid calling the original constructor and you can test the instance.
If it is final then unit testing it becomes quite hard. If you are not actually unit testing this particular class, you should either mock the picture object entirely or not at all.
BTW, this is why you shouldn't allow your constructors to do work: it results in code that is hard to test & mock. Separating object initializations from your logic is a good thing. Probably what you'd want here is an additional constructor that takes filename and dimensions as constructor args.

Extending a class with final attributes. Mockup

I usually set each attribute of a class as final (only for attributes that will be initialized within the constructor).
The point is that I am now implementing a Mockup of an object for testing purpose. This Mockup extends the class that it is mocking up and this class has some final attributes. Therefore I'm forced to call the super() constructor within the constructor of the Mockup object. This breaks however the utility of the Mockup because I don't want it to initialize all of the attributes in the way the normal class does it. I'd rather call the Mockup constructor without calling to super() and doing whatever I want.
My question is: Is it a good practice to define attributes as final as long as they will force you to call the class constructor in the Mockup?
EDIT: I add some code. The problem in this case is that I'm using a singleton, I know that this is not a good idea when testing but in this case I cannot change it. So my intention is not to call this method in the Mockup.
public class ReportsDataManager {
private final Map<String, List<String>> translations;
public ReportsDataManager() {
this.translations = GenericUtils.getTranslation();
}
}
Declaring attributes final is a very good practice when you can do it. It confers immutability - guaranteed thread safety. Breaking it to mock is a bad idea. Your design should serve the user's needs, not your testing convenience.
If you wish to mock the class, give it an interface and mock the interface. Also, mocks aren't stubs. It sounds like you're creating a stub, rather than a mock.
If you do wish to create a mock, pick a library that generates mocks for interfaces for you.
In general I'd say that if a practice you use makes testing your code more difficult then the practice may be a smell.
Try to decide exactly what you want to achieve by setting variables final. Would protected be acceptable?
You can sidestep the final restriction with standard reflection. Since you are in the context of a mockup, this wouldn't cause much problems, I suppose. Just beware of multithreading issues: the JVM will assume the field adheres to the final semantics and will optimize with that in mind.

Unit Testing with JUnit

As i understand it, the correct way to test private methods is via reflection? So if we test a method via reflection, we need to make an instance of the class, get the method, invoke it and so on. However, what do we do if the class that we create uses data from other objects that will return null / be null without the correct previously made objects.
Thanks
I personally think you should avoid writing tests on private methods. Using reflection to me is a design smell - you should ideally write tests only against the exposed public interface of your class.
If you feel the need to test a private method, then this suggests to me that you should do one of the following:
Recognise that the method really should be part of the public interface and make it public
Write a test against some existing public methods of the class that indirectly test the private method
Write a new public method that exposes the behaviour you wish to test
Refactor the behaviour out into another class which you can test (thanks Tom for the extra idea!)
As i understand it, the correct way to test private methods is via
reflection?
It's the only way (if you're only testing the private method, and not some other public method that calls the private method), as you cannot access the private methods from outside of the class (except with reflection). I don't usually write separate tests for private-methods, but it can be useful.
what do we do if the class that we create uses data from other objects
that will return null / be null without the correct previously made
objects.
In unit-tests, you "mock" the outside dependencies, either using a mocking-library, such as Mockito or some other, or write anonymous or separate mocking classes implementing the interface of the dependency. The idea is that you define some exact behavior for the outside dependencies, so their behavior won't affect the testing of the actual class. If the fields holding the references are private, you need to use reflection to inject the objects into them.
In integration-testing, you use the actual implementations of the outside dependencies.
You can use an existing instance of the class (say, the instance on which you've already tested the public methods).
Now just invoke the private method (found through reflection) of that instance, which, presumably, must have all the 'previously made' objects.

annotation to make a private method public only for test classes [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
Who has a solution for that common need.
I have a class in my application.
some methods are public, as they are part of the api,
and some are private, as they for internal use of making the internal flow more readable
now, say I want to write a unit test, or more like an integration test, which will be located in a different package, which will be allowed to call this method, BUT, I want that normal calling to this method will not be allowed if you try to call it from classes of the application itself
so, I was thinking about something like that
public class MyClass {
public void somePublicMethod() {
....
}
#PublicForTests
private void somePrivateMethod() {
....
}
}
The annotation above will mark the private method as "public for tests"
which means, that compilation and runtime will be allowed for any class which is under the test... package , while compilation and\or runtime will fail for any class which is not under the test package.
any thoughts?
is there an annotation like this?
is there a better way to do this?
it seems that the more unit tests you write, to more your inforced to break your encapsulation...
The common way is to make the private method protected or package-private and to put the unit test for this method in the same package as the class under test.
Guava has a #VisibleForTesting annotation, but it's only for documentation purposes.
If your test coverage is good on all the public method inside the tested class, the privates methods called by the public one will be automatically tested since you will assert all the possible case.
The JUnit Doc says:
Testing private methods may be an indication that those methods should be moved into another class to promote reusability.
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the aid of the PrivilegedAccessor. For details on how to use it, read this article.
Consider using interfaces to expose the API methods, using factories or DI to publish the objects so the consumers know them only by the interface. The interface describes the published API. That way you can make whatever you want public on the implementation objects and the consumers of them see only those methods exposed through the interface.
dp4j has what you need. Essentially all you have to do is add dp4j to your classpath and whenever a method annotated with #Test (JUnit's annotation) calls a method that's private it will work (dp4j will inject the required reflection at compile-time). You may also use dp4j's #TestPrivates annotation to be more explicit.
If you insist on also annotating your private methods you may use Google's #VisibleForTesting annotation.
An article on Testing Private Methods lays out some approaches to testing private code. using reflection puts extra burden on the programmer to remember if refactoring is done, the strings aren't automatically changed, but I think it's the cleanest approach.
Or you can extract this method to some strategy object. In this case you can easily test extracted class and don't make method public or some magic with reflection/bytecode.
Okay, so here we have two things that are being mixed. First thing, is when you need to mark something to be used only on test, which I agree with #JB Nizet, using the guava annotation would be good.
A different thing, is to test private methods. Why should you test private methods from the outside? I mean.. You should be able to test the object by their public methods, and at the end that its behavior. At least, that we are doing and trying to teach to junior developers, that always try to test private methods (as a good practice).
I am not aware of any such annotation, however the following may be of value: unit testing private methods
or the following: JMockit
You can't do this, since then how could you even compile your tests? The compiler won't take the annotation into account.
There are two general approaches to this
The first is to use reflection to access the methods anyway
The second is to use package-private instead of private, then have your tests in the same package (but in a different module). They will essentially be private to other code, but your tests will still be able to access them.
Of course, if you do black-box testing, you shouldn't be accessing the private members anyway.
We recently released a library that helps a lot to access private fields, methods and inner classes through reflection : BoundBox
For a class like
public class Outer {
private static class Inner {
private int foo() {return 2;}
}
}
It provides a syntax like :
Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();
The only thing you have to do to create the BoundBox class is to write #BoundBox(boundClass=Outer.class) and the BoundBoxOfOuter class will be instantly generated.
As much as I know there is no annotation like this. The best way is to use reflection as some of the others suggested. Look at this post:
How do I test a class that has private methods, fields or inner classes?
You should only watch out on testing the exception outcome of the method. For example: if u expect an IllegalArgumentException, but instead you'll get "null" (Class:java.lang.reflect.InvocationTargetException).
A colegue of mine proposed using the powermock framework for these situations, but I haven't tested it yet, so no idea what exactly it can do. Although I have used the Mockito framework that it is based upon and thats a good framework too (but I think doesn't solve the private method exception issue).
It's a great idea though having the #PublicForTests annotation.
Cheers!
I just put the test in the class itself by making it an inner class:
https://rogerkeays.com/how-to-unit-test-private-methods

Categories

Resources