Search code examples
c#reflectionmstest

C# How do I invoke a private overloaded method using System.Reflection when number of arguments are equal


I have a class called TicketManager. This class has two private methods private void Validate(Ticket ticket) and an overload private void Validate(TicketResponse ticketResponse).

When I use the BindingFlags without specifying the Type[] I get an Ambiguous Match Exception.

The following code is my unit test using MSTest.

//testing private validation method using reflection
    [TestMethod]
    [ExpectedException(typeof(TargetInvocationException))]
    public void Validate_TicketResponseIsInvalid_ReturnsValidationException()
    {
        //Arrange
        TicketManager ticketManager = new TicketManager(ticketRepository);
        Ticket t = new Ticket { AccountId = 1, Text = "How do I test a private method in C#?", TicketNumber = 5 };
        TicketResponse tr = new TicketResponse { Ticket = t, IsClientResponse = false, Date = DateTime.Now };

        //reflection
        MethodInfo methodInfo = typeof(TicketManager).GetMethod("Validate", new Type[] { typeof(TicketResponse) });
        object[] parameters = {tr};
        //Act
        methodInfo.Invoke(ticketManager, parameters); //throws NullReferenceException

        //Assert
        //assertion happens using attribute added to method
    }

Solution

  • You need to use an overload that lets you specify the BindingFlags, to specify NonPublic. For example:

        MethodInfo methodInfo = typeof(TicketManager).GetMethod("Validate",
            BindingFlags.NonPublic | BindingFlags.Instance,
            null, new Type[] { typeof(TicketResponse) }, null);
    

    However, in the context of testing, I wonder if this should either actually have a public API, or at least have an internal API (rather than private) and use [InternalsVisibleTo(...)] to let your test suite access it.