How do you unit test private methods?

.NetUnit TestingTddPrivate

.Net Problem Overview


I'm building a class library that will have some public & private methods. I want to be able to unit test the private methods (mostly while developing, but also it could be useful for future refactoring).

What is the correct way to do this?

.Net Solutions


Solution 1 - .Net

If you want to unit test a private method, something may be wrong. Unit tests are (generally speaking) meant to test the interface of a class, meaning its public (and protected) methods. You can of course "hack" a solution to this (even if just by making the methods public), but you may also want to consider:

  1. If the method you'd like to test is really worth testing, it may be worth to move it into its own class.
  2. Add more tests to the public methods that call the private method, testing the private method's functionality. (As the commentators indicated, you should only do this if these private methods's functionality is really a part in with the public interface. If they actually perform functions that are hidden from the user (i.e. the unit test), this is probably bad).

Solution 2 - .Net

If you are using .net, you should use the InternalsVisibleToAttribute.

Solution 3 - .Net

It might not be useful to test private methods. However, I also sometimes like to call private methods from test methods. Most of the time in order to prevent code duplication for test data generation...

Microsoft provides two mechanisms for this:

Accessors

  • Go to the class definition's source code
  • Right-click on the name of the class
  • Choose "Create Private Accessor"
  • Choose the project in which the accessor should be created => You will end up with a new class with the name foo_accessor. This class will be dynamically generated during compilation and provides all members public available.

However, the mechanism is sometimes a bit intractable when it comes to changes of the interface of the original class. So, most of the times I avoid using this.

PrivateObject class The other way is to use Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject

// Wrap an already existing instance
PrivateObject accessor = new PrivateObject( objectInstanceToBeWrapped );

// Retrieve a private field
MyReturnType accessiblePrivateField = (MyReturnType) accessor.GetField( "privateFieldName" );

// Call a private method
accessor.Invoke( "PrivateMethodName", new Object[] {/* ... */} );

Solution 4 - .Net

I don't agree with the "you should only be interested in testing the external interface" philosophy. It's a bit like saying that a car repair shop should only have tests to see if the wheels turn. Yes, ultimately I'm interested in the external behavior but I like my own, private, internal tests to be a bit more specific and to the point. Yes, if I refactor, I may have to change some of the tests, but unless it's a massive refactor, I'll only have to change a few and the fact that the other (unchanged) internal tests still work is a great indicator that the refactoring has been successful.

You can try to cover all internal cases using only the public interface and theoretically it's possible to test every internal method (or at least every one that matters) entirely by using the public interface but you may have to end up standing on your head to achieve this and the connection between the test cases being run through the public interface and the internal portion of the solution they're designed to test may be difficult or impossible to discern. Having pointed, individual tests that guarantee that the internal machinery is working properly is well worth the minor test changes that come about with refactoring - at least that's been my experience. If you have to make huge changes to your tests for every refactoring, then maybe this doesn't make sense, but in that case, maybe you ought to rethink your design entirely. A good design should be flexible enough to allow for most changes without massive redesigns.

Solution 5 - .Net

In the rare cases I have wanted to test private functions, I have usually modified them to be protected instead, and the I have written a subclass with a public wrapper function.

The Class:

...

protected void APrivateFunction()
{
    ...
}

...

Subclass for testing:

...

[Test]
public void TestAPrivateFunction()
{
    APrivateFunction();
    //or whatever testing code you want here
}

...

Solution 6 - .Net

I think a more fundamental question should be asked is that why are you trying to test the private method in the first place. That is a code smell that you're trying to test the private method through that class' public interface whereas that method is private for a reason as it's an implementation detail. One should only be concerned with the behaviour of the public interface not on how it's implemented under the covers.

If I want to test the behaviour of the private method, by using common refactorings, I can extract its code into another class (maybe with package level visibility so ensure it's not part of a public API). I can then test its behaviour in isolation.

The product of the refactoring means that private method is now a separate class that has become a collaborator to the original class. Its behaviour will have become well understood via its own unit tests.

I can then mock its behaviour when I try to test the original class so that I can then concentrate on test the behaviour of that class' public interface rather than having to test a combinatorial explosion of the public interface and the behaviour of all its private methods.

I see this analogous to driving a car. When I drive a car I don't drive with the bonnet up so I can see that the engine is working. I rely on the interface the car provides, namely the rev counter and the speedometer to know the engine is working. I rely on the fact that the car actually moves when I press the gas pedal. If I want to test the engine I can do checks on that in isolation. :D

Of course testing private methods directly may be a last resort if you have a legacy application but I would prefer that legacy code is refactored to enable better testing. Michael Feathers has written a great book on this very subject. http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052

Solution 7 - .Net

Private types, internals and private members are so because of some reason, and often you don’t want to mess with them directly. And if you do, chances are that you’ll break later, because there is no guarantee that the guys who created those assemblies will keep the private/internal implementations as such.

But ,at times, when doing some hacks/exploration of compiled or third party assemblies, I have myself ended up wanting to initialize a private class or a class with a private or internal constructor. Or, at times, when dealing with pre-compiled legacy libraries that I can’t change - I end up writing some tests against a private method.

Thus born the AccessPrivateWrapper - http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html - it's is a quick wrapper class that’ll make the job easy using C# 4.0 dynamic features and reflection.

You can create internal/private types like

    //Note that the wrapper is dynamic
    dynamic wrapper = AccessPrivateWrapper.FromType
        (typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");

    //Access the private members
    wrapper.PrivateMethodInPrivateClass();

Solution 8 - .Net

Well you can unit test private method in two ways

  1. you can create instance of PrivateObject class the syntax is as follows

     PrivateObject obj= new PrivateObject(PrivateClass);
     //now with this obj you can call the private method of PrivateCalss.
     obj.PrivateMethod("Parameters");
    
  2. You can use reflection.

     PrivateClass obj = new PrivateClass(); // Class containing private obj
     Type t = typeof(PrivateClass); 
     var x = t.InvokeMember("PrivateFunc", 
         BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public |  
             BindingFlags.Instance, null, obj, new object[] { 5 });
    

Solution 9 - .Net

I've also used the InternalsVisibleToAttribute method. It's worth mentioning too that, if you feel uncomfortable making your previously private methods internal in order to achieve this, then maybe they should not be the subject of direct unit tests anyway.

After all, you're testing the behaviour of your class, rather than it's specific implementation - you can change the latter without changing the former and your tests should still pass.

Solution 10 - .Net

There are 2 types of private methods. Static Private Methods and Non Static Private methods(Instance Methods). The following 2 articles explain how to unit test private methods with examples.

  1. [Unit Testing Static Private Methods][1]
  2. [Unit Testing Non Static Private Methods][2]

[1]: http://venkatcsharpinterview.blogspot.com/2011/07/unit-testing-private-static-method-in-c.html "Unit Testing Static Private Methods" [2]: http://venkatcsharpinterview.blogspot.com/2011/07/unit-test-private-method-in-c-net.html "Unit Testing Non Static Private Methods"

Solution 11 - .Net

MS Test has a nice feature built in that makes private members and methods available in the project by creating a file called VSCodeGenAccessors

[System.Diagnostics.DebuggerStepThrough()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
    internal class BaseAccessor
    {

        protected Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject m_privateObject;

        protected BaseAccessor(object target, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
        {
            m_privateObject = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(target, type);
        }

        protected BaseAccessor(Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
            :
                this(null, type)
        {
        }

        internal virtual object Target
        {
            get
            {
                return m_privateObject.Target;
            }
        }

        public override string ToString()
        {
            return this.Target.ToString();
        }

        public override bool Equals(object obj)
        {
            if (typeof(BaseAccessor).IsInstanceOfType(obj))
            {
                obj = ((BaseAccessor)(obj)).Target;
            }
            return this.Target.Equals(obj);
        }

        public override int GetHashCode()
        {
            return this.Target.GetHashCode();
        }
    }

With classes that derive from BaseAccessor

such as

[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class SomeClassAccessor : BaseAccessor
{

    protected static Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType m_privateType = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType(typeof(global::Namespace.SomeClass));

    internal SomeClassAccessor(global::Namespace.Someclass target)
        : base(target, m_privateType)
    {
    }

    internal static string STATIC_STRING
    {
        get
        {
            string ret = ((string)(m_privateType.GetStaticField("STATIC_STRING")));
            return ret;
        }
        set
        {
            m_privateType.SetStaticField("STATIC_STRING", value);
        }
    }

    internal int memberVar    {
        get
        {
            int ret = ((int)(m_privateObject.GetField("memberVar")));
            return ret;
        }
        set
        {
            m_privateObject.SetField("memberVar", value);
        }
    }

    internal int PrivateMethodName(int paramName)
    {
        object[] args = new object[] {
            paramName};
        int ret = (int)(m_privateObject.Invoke("PrivateMethodName", new System.Type[] {
                typeof(int)}, args)));
        return ret;
    }

Solution 12 - .Net

On CodeProject, there is an article that briefly discusses pros and cons of testing private methods. It then provides some reflection code to access private methods (similar to the code Marcus provides above.) The only issue I've found with the sample is that the code doesn't take into account overloaded methods.

You can find the article here:

http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

Solution 13 - .Net

Declare them internal, and then use the InternalsVisibleToAttribute to allow your unit test assembly to see them.

Solution 14 - .Net

I tend not to use compiler directives because they clutter things up quickly. One way to mitigate it if you really need them is to put them in a partial class and have your build ignore that .cs file when making the production version.

Solution 15 - .Net

You should not be testing the private methods of your code in the first place. You should be testing the 'public interface' or API, the public things of your classes. The API are all the public methods you expose to outside callers.

The reason is that once you start testing the private methods and internals of your class you are coupling the implementation of your class (the private things) to your tests. This means that when you decide to change your implementation details you will also have to change your tests.

You should for this reason avoid using InternalsVisibleToAtrribute.

Here is a great talk by Ian Cooper which covers this subject: Ian Cooper: TDD, where did it all go wrong

Solution 16 - .Net

Sometimes, it can be good to test private declarations. Fundamentally, a compiler only has one public method: Compile( string outputFileName, params string[] sourceSFileNames ). I'm sure you understand that would be difficult to test such a method without testing each "hidden" declarations!

That's why we have created Visual T#: to make easier tests. It's a free .NET programming language (C# v2.0 compatible).

We have added '.-' operator. It just behave like '.' operator, except you can also access any hidden declaration from your tests without changing anything in your tested project.

Take a look at our web site: download it for free.

Solution 17 - .Net

I'm surprised nobody has said this yet, but a solution I have employed is to make a static method inside the class to test itself. This gives you access to everything public and private to test with.

Furthermore, in a scripting language (with OO abilities, like Python, Ruby and PHP), you can make the file test itself when run. Nice quick way of making sure your changes didn't break anything. This obviously makes a scalable solution to testing all your classes: just run them all. (you can also do this in other languages with a void main which always runs its tests as well).

Solution 18 - .Net

I want to create a clear code example here which you can use on any class in which you want to test private method.

In your test case class just include these methods and then employ them as indicated.

  /**
   *
   * @var Class_name_of_class_you_want_to_test_private_methods_in
   * note: the actual class and the private variable to store the 
   * class instance in, should at least be different case so that
   * they do not get confused in the code.  Here the class name is
   * is upper case while the private instance variable is all lower
   * case
   */
  private $class_name_of_class_you_want_to_test_private_methods_in;

  /**
   * This uses reflection to be able to get private methods to test
   * @param $methodName
   * @return ReflectionMethod
   */
  protected static function getMethod($methodName) {
    $class = new ReflectionClass('Class_name_of_class_you_want_to_test_private_methods_in');
    $method = $class->getMethod($methodName);
    $method->setAccessible(true);
    return $method;
  }

  /**
   * Uses reflection class to call private methods and get return values.
   * @param $methodName
   * @param array $params
   * @return mixed
   *
   * usage:     $this->_callMethod('_someFunctionName', array(param1,param2,param3));
   *  {params are in
   *   order in which they appear in the function declaration}
   */
  protected function _callMethod($methodName, $params=array()) {
    $method = self::getMethod($methodName);
    return $method->invokeArgs($this->class_name_of_class_you_want_to_test_private_methods_in, $params);
  }

$this->_callMethod('_someFunctionName', array(param1,param2,param3));

Just issue the parameters in the order that they appear in the original private function

Solution 19 - .Net

For anyone who wants to run private methods without all the fess and mess. This works with any unit testing framework using nothing but good old Reflection.

public class ReflectionTools
{
	// If the class is non-static
	public static Object InvokePrivate(Object objectUnderTest, string method, params object[] args)
	{
		Type t = objectUnderTest.GetType();
		return t.InvokeMember(method,
			BindingFlags.InvokeMethod |
			BindingFlags.NonPublic |
			BindingFlags.Instance |
			BindingFlags.Static,
			null,
			objectUnderTest,
			args);
	}
	// if the class is static
	public static Object InvokePrivate(Type typeOfObjectUnderTest, string method, params object[] args)
	{
		MemberInfo[] members = typeOfObjectUnderTest.GetMembers(BindingFlags.NonPublic | BindingFlags.Static);
		foreach(var member in members)
		{
			if (member.Name == method)
			{
				return typeOfObjectUnderTest.InvokeMember(method, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, typeOfObjectUnderTest, args);
			}
		}
		return null;
	}
}

Then in your actual tests, you can do something like this:

Assert.AreEqual( 
  ReflectionTools.InvokePrivate(
    typeof(StaticClassOfMethod), 
    "PrivateMethod"), 
  "Expected Result");

Assert.AreEqual( 
  ReflectionTools.InvokePrivate(
    new ClassOfMethod(), 
    "PrivateMethod"), 
  "Expected Result");

Solution 20 - .Net

CC -Dprivate=public

"CC" is the command line compiler on the system I use. -Dfoo=bar does the equivalent of #define foo bar. So, this compilation option effectively changes all private stuff to public.

Solution 21 - .Net

MbUnit got a nice wrapper for this called Reflector.

Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);

You can also set and get values from properties

dogReflector.GetProperty("Age");

Regarding the "test private" I agree that.. in the perfect world. there is no point in doing private unit tests. But in the real world you might end up wanting to write private tests instead of refactoring code.

Solution 22 - .Net

Here is good article about unit testing of private methods. But I'm not sure what's better, to make you application designed specially for testing(it's like creating tests for testing only) or use reflexion for testing. Pretty sure most of us will choose second way.

Solution 23 - .Net

In my opinion you should only unit test your classe's public API.

Making a method public, in order to unit test it, breaks encapsulation exposing implementation details.

A good public API solves an immediate goal of the client code and solves that goal completely.

Solution 24 - .Net

I use PrivateObject class. But as mentioned previously better to avoid testing private methods.

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

Solution 25 - .Net

Here's an example, first the method signature:

private string[] SplitInternal()
{
    return Regex.Matches(Format, @"([^/\[\]]|\[[^]]*\])+")
                        .Cast<Match>()
                        .Select(m => m.Value)
                        .Where(s => !string.IsNullOrEmpty(s))
                        .ToArray();
}

Here's the test:

/// <summary>
///A test for SplitInternal
///</summary>
[TestMethod()]
[DeploymentItem("Git XmlLib vs2008.dll")]
public void SplitInternalTest()
{
    string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
    object[] values = new object[] { 2, "Martin" };
    XPathString xp = new XPathString(path, values);

    PrivateObject param0 = new PrivateObject(xp);
    XPathString_Accessor target = new XPathString_Accessor(param0);
    string[] expected = new string[] {
        "pair[path/to/@Key={0}]",
        "Items",
        "Item[Name={1}]",
        "Date"
    };
    string[] actual;
    actual = target.SplitInternal();
    CollectionAssert.AreEqual(expected, actual);
}

Solution 26 - .Net

A way to do this is to have your method protected and write a test fixture which inherits your class to be tested. This way, you are nor turning your method public, but you enable the testing.

Solution 27 - .Net

  1. If you have a legacy code then the only way to test private methods is by reflection.

  2. If it is new code then you have the following options:

  • Use reflection (to complicated)
  • Write unit test in the same class (makes the production code ugly by having test code also in it)
  • Refactor and make the method public in some kind of util class
  • Use @VisibleForTesting annotation and remove private

I prefer the annotation method, simplest and least complicated. The only issue is that we have increased the visibility which I think is not a big concern. We should always be coding to interface, so if we have an interface MyService and an implementation MyServiceImpl then we can have the corresponding test classes that is MyServiceTest (test interface methods) and MyServiceImplTest (test private methods). All clients should anyway be using the interface so in a way even though the visibility of the private method has been increased it should not really matter.

Solution 28 - .Net

You could also declare it as public or internal (with InternalsVisibleToAttribute) while building in debug-Mode:

    /// <summary>
    /// This Method is private.
    /// </summary>
#if DEBUG
    public
#else
    private
#endif
    static string MyPrivateMethod()
    {
        return "false";
    }

It bloats the code, but it will be private in a release build.

Solution 29 - .Net

You could generate the test method for the private method from Visual studio 2008. When you create a unit test for a private method, a Test References folder is added to your test project and an accessor is added to that folder. The accessor is also referred to in the logic of the unit test method. This accessor allows your unit test to call private methods in the code that you are testing. For details have a look at

http://msdn.microsoft.com/en-us/library/bb385974.aspx

Solution 30 - .Net

Also note that the InternalsVisibleToAtrribute has a requirement that your assembly be strong named, which creates it's own set of problems if you're working in a solution that had not had that requirement before. I use the accessor to test private methods. See this question that for an example of this.

Solution 31 - .Net

For JAVA language

Here, you can over-ride a particular method of the testing class with mock behavior.

For the below code:

public class ClassToTest 
{
    public void methodToTest()
    {
        Integer integerInstance = new Integer(0);
        boolean returnValue= methodToMock(integerInstance);
        if(returnValue)
        {
            System.out.println("methodToMock returned true");
        }
        else
        {
            System.out.println("methodToMock returned true");
        }
        System.out.println();
    }
    private boolean methodToMock(int value)
    {
        return true;
    }
}

Test class would be:

public class ClassToTestTest{

    @Test
    public void testMethodToTest(){

        new Mockup<ClassToTest>(){
            @Mock
            private boolean methodToMock(int value){
                return true;
            }
        };

        ....    

    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEric LabashoskyView Question on Stackoverflow
Solution 1 - .NetJeroen HeijmansView Answer on Stackoverflow
Solution 2 - .NetTcKsView Answer on Stackoverflow
Solution 3 - .NetSevenView Answer on Stackoverflow
Solution 4 - .NetDarrell PlankView Answer on Stackoverflow
Solution 5 - .NetJason JacksonView Answer on Stackoverflow
Solution 6 - .NetBig KahunaView Answer on Stackoverflow
Solution 7 - .NetamazedsaintView Answer on Stackoverflow
Solution 8 - .NetUnknownView Answer on Stackoverflow
Solution 9 - .NetphilsquaredView Answer on Stackoverflow
Solution 10 - .NetVenkatView Answer on Stackoverflow
Solution 11 - .NetMarcus KingView Answer on Stackoverflow
Solution 12 - .NetPedroView Answer on Stackoverflow
Solution 13 - .NetJames CurranView Answer on Stackoverflow
Solution 14 - .NetswilliamsView Answer on Stackoverflow
Solution 15 - .Netcda01View Answer on Stackoverflow
Solution 16 - .NetLudovic DuboisView Answer on Stackoverflow
Solution 17 - .NetrubeView Answer on Stackoverflow
Solution 18 - .NetDamon HoganView Answer on Stackoverflow
Solution 19 - .NetErick StoneView Answer on Stackoverflow
Solution 20 - .NetMark HarrisonView Answer on Stackoverflow
Solution 21 - .NetCarl BergquistView Answer on Stackoverflow
Solution 22 - .NetJohnny_DView Answer on Stackoverflow
Solution 23 - .NetjpchaunyView Answer on Stackoverflow
Solution 24 - .NetvsapihaView Answer on Stackoverflow
Solution 25 - .NetChuck SavageView Answer on Stackoverflow
Solution 26 - .NetkiriloffView Answer on Stackoverflow
Solution 27 - .NetanujView Answer on Stackoverflow
Solution 28 - .NetAlex HView Answer on Stackoverflow
Solution 29 - .NetSarathView Answer on Stackoverflow
Solution 30 - .NetChuck DeeView Answer on Stackoverflow
Solution 31 - .NetAmit KaneriaView Answer on Stackoverflow