Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a private constructor in Java application? [duplicate]

If a class contains a bunch of static methods, in order to make sure no one by mistake initializes an instance of this class, I made a private constructor:

private Utils() { } 

Now .. how could this be tested, given that constructor can't be seen? Can this be test covered at all?

like image 597
James Raitsev Avatar asked Dec 29 '12 01:12

James Raitsev


People also ask

How do you mock a private constructor?

// Use the launcher of powermock @RunWith(PowerMockRunner. class) public class MyTestClass { @Test // Prepare the class for which we want to mock a static method @PrepareForTest(SiteUtil. class) public void myTest() throws Exception{ // Build the mock of Site Site mockSite = PowerMockito. mock(Site.

How do you call a private constructor from a different class?

The method java. lang. Class. getDeclaredConstructor() can be used to obtain the constructor object for the private constructor of the class.

Can we call private constructor in Java?

Yes, we can declare a constructor as private. If we declare a constructor as private we are not able to create an object of a class. We can use this private constructor in the Singleton Design Pattern.

How do you test a private method in Java?

If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection. Internally we're using helpers to get/set private and private static variables as well as invoke private and private static methods.


2 Answers

Using reflection, you can invoke a private constructor:

Constructor<Util> c = Utils.class.getDeclaredConstructor(); c.setAccessible(true); Utils u = c.newInstance(); // Hello sailor 

However, you can make even that not possible:

private Utils() {     throw new UnsupportedOperationException(); } 

By throwing an exception in the constructor, you prevent all attempts.


I would make the class itself final too, just "because":

public final class Utils {     private Utils() {         throw new UnsupportedOperationException();     } } 
like image 149
Bohemian Avatar answered Oct 02 '22 12:10

Bohemian


Test the intent of the code .. always :)

For example: If the point of the constructor being private is to not be seen then what you need to test is this fact and nothing else.

Use the reflection API to query for the constructors and validate that they have the private attribute set.

I would do something like this:

@Test() public void testPrivateConstructors() {     final Constructor<?>[] constructors = Utils.class.getDeclaredConstructors();     for (Constructor<?> constructor : constructors) {         assertTrue(Modifier.isPrivate(constructor.getModifiers()));     } } 

If you want to have a proper test for the object construction, you should test the public API which allows you to get the constructed object. That's the reason the said API should exist: to build the objects properly so you should test it for that :).

like image 24
Mihai Toader Avatar answered Oct 02 '22 10:10

Mihai Toader