Home > OS >  Private method testing in NUnit
Private method testing in NUnit

Time:11-16

Issue is simple but quite hard to bypass - I need to test private method without simply changing code to make it public. Doing it wouldn't be the end of the world, but this class contains one public method and set of private methods dedicated to that one public method, and changing it would be bad practice.

I have managed to found "solution" online, but it does not seem to work. Test fails with exception System.Reflection.TargetException : Object does not match target type..

Here is simplified code:

        private Class _class;
        private List<Item> _list;
        private List<Item> _resultList;

        [SetUp]
        public void SetUp()
        {
            _class = new Class();
            _list = new List<Item>();
            _resultList = new List<Item>();
            //do stuff to prepare data
        }

        [Test]
        public void TestMethod_Equal()
        {
            var method = GetMethod("PrivateMethodName");
            var result = method.Invoke(this, new object[] { _list }); //this private method needs `List<item>`
            Assert.That(_resultList, Is.EqualTo(result));
        }

        private MethodInfo GetMethod(string methodName) //the online solution
        {
            if (string.IsNullOrWhiteSpace(methodName))
                Assert.Fail("methodName cannot be null or whitespace");

            var method = this._class.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);

            if (method == null)
                Assert.Fail(string.Format("{0} method not found", methodName));

            return method;
        }

CodePudding user response:

You need an instance of the class to be able to invoke the method against that instance. You also need to use the same type of said instance when locating the MethodInfo for the class. I've adapted your code to an example below:

void Main()
{
    var myInstanceUnderTest = new MyConcreteClass();
    var method = myInstanceUnderTest.GetType().GetPrivateMethod("SomePrivateMethod");

    method.Invoke(myInstanceUnderTest, null);
}

public class MyConcreteClass 
{
    private void SomePrivateMethod() 
    {
        Console.WriteLine("I ran!");    
    }   
}

public static class Helpers 
{
    public static MethodInfo GetPrivateMethod(this Type myType, string methodName) //the online solution
    {
        if (string.IsNullOrWhiteSpace(methodName))
            throw new Exception("methodName cannot be null or whitespace");

        var method = myType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);

        if (method == null)
            throw new Exception(string.Format("{0} method not found", methodName));

        return method;
    }
}
  • Related