Fundamentals of Unit Testing: Don’t Test Your Private Method

In this article, we will discuss the very controversial and important topic of whether the testing of a private method or private function is ethical.

Hi, you are in the “Fundamentals of Unit testing” article series. Here we are talking about unit testing methodology. In our previous article we saw the fundamentals of unit testing. You can read all our previous articles here.

In this article, we will discuss one very controversial and important topic. Is the testing of a private method or private function ethical?

Now, why does this questions arise? What's wrong with a private function? Nothing is wrong with a private function but let's remind ourselves of the functionality and philosophy of a private function. We know that private members are very secure in a class because access to it is not permitted from the outer world. Sometimes people say that it's unethical to declare a private member, but I don't think so, it's my personal view. Ok, so return to our discussion. Private members are very secure ones and only the public members of the same class can execute it.

Now, let's think that we have done some operation in one private function and called the function from a public method.

And we are testing the public method and it's giving my desired output. If this is the scenario, then we have already tested the private method implicitly. Is it not?

So, this is the logic behind saying that “Don't test private methods” explicitly.

Now, again this is not universally acceptable. People think that they are doing unit testing and the concept of a unit is a small amount of code. They are not bothered by the behavior of the code. They think and feel that there is no harm in testing a private method.

Anyway, both are correct in their point and our intention is not to indulge in this debate but to learn to test private methods in unit testing.

So, let's create a private method that we will be testing. Have a look at the following code.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace TestProjectLibrary

{

    public class testMath

    {

        private int Add(int a,int b)

        {

            return a + b;

        }

    }

}

We have created a simple testMath class and have defined the Add() private method that will return the addition of two parameters.

Now, let's define our unit test method.

using System;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using TestProjectLibrary;

namespace UnitTest

{

    [TestClass]

    public class UnitTest1

    {

        [TestMethod]

        public void TestMethod1()

        {

            PrivateObject pobj = new PrivateObject(typeof(testMath));

            var result = pobj.Invoke("Add", 10, 10);

            Assert.AreEqual(20, result);

        }

    }

}

We are seeing that we have created a PrivateObject class to execute the private method, PrivateObject contains an “Invoke” method that we are using to call a private method by passing three parameters, the first one is a method name and the last two are arguments to pass the method.

Here is sample output.

Unit test

And we are seeing that the test has passed successfully.

Conclusion

I hope you have understood how to call and execute a private method in this article. In the next article we will understand a few more important concepts of unit testing.