Search code examples
c#unit-testingreflectionaccess-levels

Unit test faces NullReferenceException when try to access a private accessor


In the main application:

namespace ConsoleApplication1
{
    public class Patient
    {
    ...
        public double height { get; private set; }

And in unit test:

Patient p1=new Patient();
BindingFlags flags=BindingFlags.Instance | BindingFlags.NonPublic;
typeof(Patient).GetField("height", flags).SetValue(p1, "67.2");

My unit test does not work and it gives me

UnitTest.MyTest.idealCal threw exception: System.NullReferenceException: Object reference not set to an instance of an object.

The error occures at the line of SetValue

How to fix it?


Solution

  • You're trying to retrieve a Field but you're actually using a Property.

    Consider this situation:

    public class X
    {
        public double Height { get; private set; }
    }
    

    You can now set a value using this code:

    void Main()
    {
        var obj = new X();
        var property = typeof(X).GetProperty("Height", BindingFlags.Instance | BindingFlags.Public);
        var setMethod = property.GetSetMethod(true);
        setMethod.Invoke(obj, new object[]{ 5.0 });
        Console.WriteLine (obj.Height);
    }
    

    The working is simple: get the property (notice naming conventions) which is public, get its private set method (that's what the true argument is for) and invoke that setter with the value you wish to set it as.

    Do note that accessing private members as part of a unit test is typically an indication you're doing something wrong. This is a too big topic to elaborate on here though.