Click here to Skip to main content
15,120,668 members
Articles / Programming Languages / C#
Posted 1 Mar 2005


136 bookmarked

How to Test Private and Protected methods in .NET

Rate me:
Please Sign up or sign in to vote.
4.83/5 (68 votes)
1 Mar 20057 min read
This article explains some theory behind testing/not testing private methods, and then provides and walks through a downloadable code sample to demonstrate these testing techniques.


Test Driven Development is the practice of (1) writing tests, (2) writing code that passes those tests, and (3) then refactoring. This concept is becoming very popular in the .NET community due to the quality assurance that it adds. While it is easy to test public methods, the natural question emerges "How do I test protected and private methods?"

This article will:

  • Summarize some key points of the "Should-you-even-test private methods debate"?
  • Make the case that it is still useful to at least know how to test private and protected methods - regardless of which side of the debate you're on.
  • Provide the theory and downloadable code sample to demonstrate these testing techniques.

Background Theory

Should You Test Private Methods?

A Google search will show you that there's a lot of debate about using private methods, let alone testing them. The table below summarizes some of the common views of the pro and con for both issues.

Use private methods
  • Encapsulation - Private methods provide encapsulation, which makes the code easier for the end client to use
  • Refactoring - It is easier to refactor private methods because they are never directly called by external clients, therefore changing the signature won't break any method calls.
  • Validation - Unlike public methods that must validate all input because they are called by external clients, private methods are called safely within the class and don't require the same rigor of validation - the inputs should have been already validated in the public methods.
  • Test Scope - Exposing every method as public greatly increases the test scope. Private methods are used only how the developer intended them, whereas public methods need to be tested for every possible case which required a broader test scope.
  • Didn't Refactor - If a class is complicated enough to merit private members, then it should be refactored.
  • Hides Functionality - Private methods (if designed correctly) provide useful features that clients may want access to, so any private method worth testing should really be public.
Test private methods
  • Test Control - Private methods can contain complex logic and it increases test control to be able to directly access the method and test it, instead of needing to indirectly accessing it through a public method.
  • Principle - Unit Testing is about testing the smallest functional piece of code; private methods are functional pieces of code, therefore on principle private methods should be testable.
  • Already Covered - Only the public interface should be tested. Private methods should already have thorough test coverage from being called by the public methods that are tested.
  • Brittle Code - If you refactor the code, and juggle around the private methods, and if you had tests linked to those private methods, then you need to juggle around your tests too.

There are bright and experienced people on both sides of the issue. So while I have no intention or expectation of ending the "should I test private method" debate, there is still value for both sides to know how to test them. Even if you think that private methods should not be tested:

  • Your opinion will be more influential if you can at least show that you are able to test them, but choose not to (i.e. you're not saying "Don't test private methods" simply because you don't know how).
  • Having the option of testing non-public methods lets you see what really works best for your team over time.
  • As long as there are still some valid situations, it's worth having a convenient way to test them.

Good Criteria and Inadequate Techniques

Andrew Hunt and David Thomas explain in their book, Pragmatic Unit Testing in C# with NUnit, that good unit tests are ATRIP:

  • Automatic
  • Thorough
  • Repeatable
  • Independent
  • Professional

There are three additional criteria that any testing overhead for private/protected methods should meet:

  • Transparency - Don't alter the System Under Test (SUT), such as adding wrapper methods in the production code.
  • Scope - Be able to run in both Debug and Release mode.
  • Simplicity - Have minimal overhead, and hence be easy to change and simple enough to introduce minimal risk.

Keeping these criteria in mind, there are several strategies that fall short:

Don't have any private methods.
  • This avoids the issue.
Use the directives #if DEBUG ... #endif to wrap a public method which in turns wraps the private method. The unit tests can now indirectly access that private method through the public wrapper. (This is a method that I myself have used many times, and found it to be tedious and non-object oriented).
  • This only works in Debug mode.
  • This is procedural and not object-oriented. We would need to wrap the individual methods in both the production code and unit tests.
  • This alters the SUT by adding the public method wrappers.
Use the [Conditional("DEBUG")] attribute on public methods that wrap the private methods.
  • This only works in Debug mode.
Create internal methods to access the private method; then have a public test class elsewhere in the assembly that wraps those internal methods with public ones.
  • This alters the release code by adding the internal hooks, ultimately making the private methods accessible in production.
  • This requires a lot of extra coding, and is hence brittle.

Testing Protected Methods

A protected method is visible only to derived classes, therefore it is not immediately available to a test suite. For example, suppose we wanted to test the method from ClassLibrary1.MyObject:

protected string MyProtectedMethod(string strInput, int i32Value) 
    return this.Name + ": " + strInput + ", " + 

The book Pragmatic Unit Testing in C# with NUnit explains one solution: make a derived class MyObjectTester that inherits class MyObject, and then create a public method TestMyProtectedMethod that wraps the protected one. For example:

public new string TestMyProtectedMethod(string strInput, int i32Value) 
    return base.MyProtectedMethod(strInput, 

This approach is simple, yet meets all the criteria:

TransparencyBy using inheritance and putting the MyObjectTester class in the UnitTests assembly, it doesn't add any new code to the production assembly.
ScopeNothing in this approach depends on Debug-only techniques.
SimplicityAlthough this approach requires a new derived class, and an additional public wrapper method for each protected method, it is object-oriented and type safe.

Testing Private Methods

Testing private methods is a little more involved; but we can still do it using System.Reflection. You can use Reflection to dynamically access methods of a type, including both instance and static private methods. Note that accessing private methods does require the ReflectionPermission, but that is not a problem for Unit Tests running on a development machine or build server.

Suppose we wanted to test the private method MyPrivateMethod from ClassLibrary1.MyObject:

private string MyPrivateMethod(string strInput, DateTime dt, double 
    return this.Name + ": " + strInput + ", " + 
     dt.ToString() + ", " + dbl.ToString();

One solution is to create a UnitTestUtilities project with a helper class to call the test method via reflection. For example, the download solution has the following methods in UnitTestUtilities.Helper:

public static object RunStaticMethod(System.Type t, string strMethod, 
 object [] aobjParams) 
    BindingFlags eFlags = 
     BindingFlags.Static | BindingFlags.Public | 
    return RunMethod(t, strMethod, 
     null, aobjParams, eFlags);
} //end of method

public static object RunInstanceMethod(System.Type t, string strMethod, 
 object objInstance, object [] aobjParams) 
    BindingFlags eFlags = BindingFlags.Instance | BindingFlags.Public | 
    return RunMethod(t, strMethod, 
     objInstance, aobjParams, eFlags);
} //end of method
private static object RunMethod(System.Type t, string 
 strMethod, object objInstance, object [] aobjParams, BindingFlags eFlags) 
    MethodInfo m;
        m = t.GetMethod(strMethod, eFlags);
        if (m == null)
             throw new ArgumentException("There is no method '" + 
              strMethod + "' for type '" + t.ToString() + "'.");
        object objRet = m.Invoke(objInstance, aobjParams);
        return objRet;
} //end of method

Private method RunMethod takes in the necessary parameters that Reflection needs to invoke a method, and then returns the value. It has two public methods that wrap this: RunStaticMethod and RunInstanceMethod for static and instance methods respectively.

Walking through RunMethod, it first gets the

from a type. Because we expect this to only be called for existing methods, a null method triggers an Exception. Once we have the MethodInfo, we can invoke the method given the instantiated object (null for static methods) and the parameter array.

We could use this Utility in an NUnit test like so:

[Test] public void TestPrivateInstanceMethod()
    string strExpected = "MyName: Hello, 5/24/2004 
     12:00:00 AM, 2.1";
    ClassLibrary1.MyObject objInstance 
     = new MyObject("MyName");
    object obj = 
     typeof(ClassLibrary1.MyObject), "MyPrivateMethod",
     objInstance, new object[3] {"Hello", 
     new DateTime(2004,05,24), 2.1});
    string strActual = Convert.ToString(obj);
TransparencyThe only extra code we created - UnitTestUtilities, is not shipped in production.
ScopeNothing in this approach depends on Debug-only techniques.
SimplicityThis approach can call any method with a single call. Once you have the UnitTestUtilities, the only complication is creating the correct parameters (method name, data types, etc...) for RunInstanceMethod or RunStaticMethod. Because the method is being dynamically called, the parameters aren't checked at compile time.


While there is a debate on whether or not to test private methods, at least we have the ability to do so. We can test protected methods using inheritance to create a derived TesterClass that wraps the base protected methods with public ones. We can test private methods using Reflection, which can be abstracted to a UnitTestUtility helper class. Both of these techniques can help to improve test coverage.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
United States United States
Tim Stall is a Chicago-based technical consultant for Computer Sciences Corporation (, a leading global IT services company. In addition to his expertise in Microsoft.Net development projects and enterprise architecture, Tim's .Net experience includes, writing technical publications, leading internal training, and having MCAD certification. His blog is at

Comments and Discussions

QuestionA better way to test private methods. Pin
Magnificent Skippy6-Oct-21 8:44
MemberMagnificent Skippy6-Oct-21 8:44 
Questionprivate method testing Pin
Member 131663332-May-17 3:51
MemberMember 131663332-May-17 3:51 
PraiseRegarding testing private and protected methods Pin
Member 1278099024-Mar-17 2:22
MemberMember 1278099024-Mar-17 2:22 
GeneralMy vote of 5 Pin
Callindrill23-Jun-16 13:15
MemberCallindrill23-Jun-16 13:15 
QuestionLicense usage Details Pin
Vinod S M21-Sep-15 23:52
MemberVinod S M21-Sep-15 23:52 
AnswerAnother, easier method to get internal access that you didn't mention Pin
ErikEckhardt11-Sep-15 13:31
MemberErikEckhardt11-Sep-15 13:31 
QuestionThis is retarded. Java gives unit tests access to protected methods by default Pin
Member 1076997923-Apr-14 7:14
MemberMember 1076997923-Apr-14 7:14 
GeneralMy vote of 5 Pin
jasonalls30-Dec-12 23:48
professionaljasonalls30-Dec-12 23:48 
SuggestionOther options Pin
Vasil Trifonov18-Nov-12 23:13
MemberVasil Trifonov18-Nov-12 23:13 
QuestionUsing the _Accessor Extension Pin
Philipp Kratzer2-May-12 4:51
MemberPhilipp Kratzer2-May-12 4:51 
GeneralArguments for Not Testing Private Methods Don't Hold Water Pin
Pickle Pumpers10-Aug-10 5:34
MemberPickle Pumpers10-Aug-10 5:34 
GeneralIn VSTS2008 or later, the IDE can create a private method accessor for any private method Pin
maguschen29-Jun-09 0:06
Membermaguschen29-Jun-09 0:06 
GeneralGreat Article Pin
WAHW23-Apr-08 14:53
MemberWAHW23-Apr-08 14:53 
GeneralExcellent article Pin
Arialdo Martini12-Dec-07 1:27
MemberArialdo Martini12-Dec-07 1:27 
GeneralNeed Some Code Example of Ajax IN Aps.NET Pin
Kamran_ku19-Sep-06 21:41
MemberKamran_ku19-Sep-06 21:41 
GeneralSuggested code change/addition Pin
jb brown19-May-06 9:51
Memberjb brown19-May-06 9:51 
GeneralRe: Suggested code change/addition Pin
jb brown19-May-06 13:33
Memberjb brown19-May-06 13:33 
GeneralPrivate Methods with different Signatures Pin
Marlon N.23-Apr-06 2:26
MemberMarlon N.23-Apr-06 2:26 
GeneralMore transparent approach Pin
Adamchuk30-Oct-05 23:48
MemberAdamchuk30-Oct-05 23:48 
AnswerRe: More transparent approach Pin
mknaup18-Jan-06 5:38
Membermknaup18-Jan-06 5:38 
GeneralRe: More transparent approach Pin
Adamchuk18-Jan-06 5:43
MemberAdamchuk18-Jan-06 5:43 
GeneralRe: More transparent approach Pin
Victor Boctor22-Jan-06 3:08
MemberVictor Boctor22-Jan-06 3:08 
GeneralTesting private classes Pin
ejp107-Apr-05 5:45
Memberejp107-Apr-05 5:45 
GeneralRe: Testing private classes Pin
ejp107-Apr-05 11:43
Memberejp107-Apr-05 11:43 
GeneralRe: Testing private classes Pin
PBernhardt15-Dec-05 5:04
MemberPBernhardt15-Dec-05 5:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.