Quantcast
Channel: Geekswithblogs.net
Viewing all articles
Browse latest Browse all 6441

Unit Testing Non-Public Methods

$
0
0

Originally posted on: http://geekswithblogs.net/abhi/archive/2013/11/20/unittesting-non-public-methods.aspx

Before we proceed any further, I should say this, Testing through this public API should be your first choice.

Alternative for Abstract Base Classes

One common case is when an abstract base class definesfunctionality in some protected methods, and there are a series of inheriting classes using those methods without overriding them. In this case, rather than choosing one inheriting member at random to test the methods, you can simply create a “Fake” class locally in your test project that inherits from the base class. This “Fake” could then expose the protected members in some public members of its own; and your tests would run against the “Fake” class.

 

The following is a simplified example of how to create a “Fake” object for this purpose:

 

         publicabstractclassMyBaseClass<T>

    {

         protectedstring MyProtectedMethod()

         {

             returntypeof(T).ToString();

         }

    }

    internalclassFakeClass : MyBaseClass<Int32>

    {

         publicstring CallMyProtectedMember()

         {

             returnbase.MyProtectedMethod();

         }

    }
       …

   [TestMethod]

   publicvoid TestMyProtectedMember()

   {

       FakeClass fake = newFakeClass();

       string retVal = fake.CallMyProtectedMember();

       Assert.AreEqual(retVal,"System.Int32");

   }


Alternative using PrivateObject

When necessary, the PrivateObject class can be used to expose non-public members to your unit tests. The class uses reflection to access the members based on a string identifier. The following is an example of how to test the private method above using PrivateObject. 


Note: the example is NOT a case where PrivateObject should be used, instead this is meant to show the simplest usage for the PrivateObject class.

 

[TestMethod()]

        publicvoid GetStringArgIsOneTest()

        {

            //Arrange

            var myClass = newMyClass();

            var privObj = newPrivateObject(myClass);

            //Act

            object retVal = privObj.Invoke("GetString", new []{typeof(Int32)}, newobject[]{1});

            //Assert

            Assert.AreEqual(retVal.ToString(),"Hello World");

        }


Unit Testing Private Static Methods

You cannot access static methods with the PrivateObject class. Instead of the PrivateObject class, you should use the PrivateType class. You can think of PrivateObject as being an object, containing only instance methods while PrivateType is a type which is how you would call static methods.

 

Example:

PrivateType privateType = newPrivateType(typeof(SomeClass));

       var actual = privateType.InvokeStatic("SomeStaticMethod", 1);

actual.Should().Be(expected);


Viewing all articles
Browse latest Browse all 6441

Trending Articles