views:

552

answers:

5

how to setup the unit test if the constructor is private (.NET)?

public class Class2 {

private Class2() //private constructor

{

}

public static Class2 getInstance()

{

 if (x == null) 

    x= new Class2();

 return x;

}

}


namespace TestUnit

{

[TestFixture]

public class Class2Tester

{

private Class2 test;

[SetUp()]

public void SetUp(){

test = new Class2(); // i cant do this. how shld i setup this.

}

+3  A: 

You don't specify a language so my answer will be generic. The typical way to do this is using reflection. You can do it directly in each test or by creating an accessor class that wraps all of the private methods/properties, including the constructor.

An example from C#/.NET

public void MyTest()
{
    MyClass class = typeof(MyClass).GetConstructor( null )
                                   .Invoke( null );
    ...
}

Or, more typically, after adding private accessors to your test project

public void MyTest()
{
    MyClass class = ((MyClass)new MyClass_Accessor()).Target;
}
tvanfosson
A: 

Basically, you should not do that. See this question.

Fabian Steeg
That question is talking about testing private methods. He just wants to use the private constructor to set up a test, not test the constructor itself.
tvanfosson
+5  A: 

The answer is: you don't. Not because you can't, but because you shouldn't.

By making the constructor private, you're saying that its behavior is not part of the public API of the class. In this case its behavior either a) doesn't affect the public API of the class which means it doesn't need to be tested. b) more likely, does affect the public API of the class, in which case, write your tests around that public API, not the black-boxed constructor.

jonathan.cone
Don't be pedantic. In a unit test, creating via the private constructor to decouple the test from the factory methods usually used to create the object is ok.
tvanfosson
Uhh, yeah, sure it is if you want to break the unit test when you refactor the internals of the constructor.
jonathan.cone
Personal preference, I guess. Typically, my default constructors don't have any actual code so there's nothing to break. The factory method would simply create an empty object and assign properties. Decoupling from the factory method allows me to set up just those parts of the object under test.
tvanfosson
+1  A: 

In java (and this assumes the only constructor is the private default constructor, otherwise checking of the array is required):

Constructor[] constructors = YourClass.class.getDeclaredConstructors();
constructors[0].setAccessible(true);
YourClass currentInstance = (YourClass) constructors[0].newInstance(null);

Then, currentInstance is available for you to use. Typically I'll only do this for code coverage, if I make a constructor private, it's generally to avoid instantiation.

MetroidFan2002
A: 

I usually don't unit test constructors at all. In this situation, the first thing you should ask yourself is if you really do need to unit test the code in this constructor. Of course the paranoid perfectionist in all of us will come out at times, so if the answer is no, I say just forget about it.

If the answer is yes, I'm of the opinion that there's a good chance that you're doing too much with your constructor and/or your class. Even if this isn't the case, there's a good chance that you can break the code that does need to be unit tested into its own public function.

Granted, there are always exceptions. But I've yet to run into an instance where I had to make a constructor private and I had to unit test it.

Jason Baker