Visual Studio allows unit testing of private methods via an automatically generated accessor class. I have written a test of a private method that compiles successfully, but it fails at runtime. A fairly minimal version of the code and the test is:
//in project MyProj
class TypeA
{
private List<TypeB> myList = new List<TypeB>();
private class TypeB
{
public TypeB()
{
}
}
public TypeA()
{
}
private void MyFunc()
{
//processing of myList that changes state of instance
}
}
//in project TestMyProj
public void MyFuncTest()
{
TypeA_Accessor target = new TypeA_Accessor();
//following line is the one that throws exception
target.myList.Add(new TypeA_Accessor.TypeB());
target.MyFunc();
//check changed state of target
}
The runtime error is:
Object of type System.Collections.Generic.List`1[MyProj.TypeA.TypeA_Accessor+TypeB]' cannot be converted to type 'System.Collections.Generic.List`1[MyProj.TypeA.TypeA+TypeB]'.
According to intellisense - and hence I guess the compiler - target is of type TypeA_Accessor. But at runtime it is of type TypeA, and hence the list add fails.
Is there any way I can stop this error? Or, perhaps more likely, what other advice do other people have (I predict maybe "don't test private methods" and "don't have unit tests manipulate the state of objects").
In VS 2005/2008 you can use private accessor to test private member,but this way was disappear in later version of VS
You can use PrivateObject Class
You can make a wrapper class around the class that contains the private method you want to test. This wrapper class contains a public method called Call_MyPrivateFunction and which in turn calls the private function of its base class.
Please note that the access level of the method schould change to [protected]
Code Example:
The unit test code could look like:
Another thought here is to extend testing to "internal" classes/methods, giving more of a white-box sense of this testing. You can use InternalsVisibleToAttribute on the assembly to expose these to separate unit testing modules.
In combination with sealed class you can approach such encapsulation that test method are visible only from unittest assembly your methods. Consider that protected method in sealed class is de facto private.
And unit test:
One way to test private methods is through reflection. This applies to NUnit and XUnit, too:
Yes, don't Test private methods.... The idea of a unit test is to test the unit by its public 'API'.
If you are finding you need to test a lot of private behavior, most likely you have a new 'class' hiding within the class you are trying to test, extract it and test it by its public interface.
One piece of advice / Thinking tool..... There is an idea that no method should ever be private. Meaning all methods should live on a public interface of an object.... if you feel you need to make it private, it most likely lives on another object.
This piece of advice doesn't quite work out in practice, but its mostly good advice, and often it will push people to decompose their objects into smaller objects.