Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing private methods in C#

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").

like image 767
junichiro Avatar asked Feb 03 '12 01:02

junichiro


People also ask

Can private methods be unit tested?

Unit Tests Should Only Test Public Methods The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.

Can we unit test private methods C#?

The unit test should only test the public interface. Each private method is an implementation detail. They contain the logic necessary to implement a piece of functionality.

Should protected methods be unit tested?

Protected methods form a different contract between your class and its future children, so you should really be testing it to a similar extent as your public interface to ensure that the contract is well defined and exercised.


1 Answers

You can use the PrivateObject class:

Class target = new Class(); PrivateObject obj = new PrivateObject(target); var retVal = obj.Invoke("PrivateMethod"); Assert.AreEqual(expectedVal, retVal); 

Note: PrivateObject and PrivateType are not available for projects targeting netcoreapp2.0 - GitHub Issue 366

like image 127
Scuttle Avatar answered Oct 12 '22 19:10

Scuttle