Reputation: 6756
Ok so i just got an assignment where i have to perform unit testing on a class with a private constructor.
Now how am i suppose to do unit testing without initializing a class when all the methods are also non static.
Is there any way i can do unit testing(without reflection)on a class with a private constructor ?
Upvotes: 10
Views: 10980
Reputation: 369
I realize that the OP (Win Coder) specifically asks for a solution that doesn't use reflection in their question. However, Google serves this as a top result for general questions about testing private constructors in C#.
So, in case you've arrived here and are okay with using reflection. Here's a solution.
In this example, I'm creating an instance of MyClass
using a private constructor that takes three (and only three) parameters of types int,
string,
and string
in that order. Types, order and number of parameters need to match.
var constructor = typeof(MyClass).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
[typeof(int), typeof(string), typeof(string)]);
var myObject = constructor?.Invoke([id, name, desc]) as MyClass;
// Run whatever unit tests you need to run on myObject.
For those who disagree with unit testing private constructors, there is an Entity Framework Core use case where your private constructor is being used publically. Douglas Gaskell mentioned it in his comment on the accepted answer.
Upvotes: 0
Reputation: 368
If you cannot make the class public, you can still test it easily by creating an instance of it this way:
var anInstance = (YourPrivateClass)Activator.CreateInstance(typeof(YourPrivateClass), true);
This will give you an instance of your class that you can then populate.
Another helpful testing bit is if you have internal methods (not private), you can access them by making internals visible to your test class. You add this line in assemblyinfo.cs of the class with the internal methods:
[assembly: InternalsVisibleTo("YourSolution.Tests")]
Upvotes: 17
Reputation: 329
It might be a singleton and you don't want the public constructor for the class. Decorate the constructor with: [ExcludeFromCodeCoverage]
Upvotes: 0
Reputation: 2597
Unit tests are typically written and run to ensure that code meets its design and behaves as intended.
Creating a non-static
class on which you cannot create an instance i.e. private constructor(s) only, might never be useful, in otherwords its is never Unit Testable
.
In order to be Unit testable:
Upvotes: 0
Reputation: 9583
If this class has a private constructor, is this to be used publicly? If not, it may be best not to unit test it. If this is the case, the code that is public should test this code in itself by calling it.
Unit testing is there to test what is to be used by the public - by interfacing code in between application layers for instance. Take an input, I want this output. That is really what unit testing is about. Unit testing doesn't care what is in the actual method. As long as it returns what you want, performs the desired action, you have a pass.
Upvotes: 8
Reputation: 59016
You should be testing through a public API -- there must be some way that the class you want to test is instantiated and used.
Upvotes: 2