Testing a private field using MSTest

10,263

Solution 1

The way to get private fields or methods in general is to use Reflection. However, the unit test framework includes a helper class, PrivateObject, to make this easier. See the docs. In general, when I've used this, I've ended up making an extension methods like the following:

public static int GetPrivateField(this MyObject obj)
{
  PrivateObject po = new PrivateObject(obj);
  return (int)po.GetField("_privateIntField");
}

If you need to get private fields in a static class, however, you will need to go with straight up reflection.

Solution 2

Nice solution offered above. For completeness, I have been using this technique for a while now (using MSTest), but have extended it for property values also.

[ExcludeFromCodeCoverage]
public static class TestExtensionMethods
{
    public static T GetFieldValue<T>(this object sut, string name)
    {
        var field = sut
            .GetType()
            .GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

        return (T)field?.GetValue(sut);
    }

    public static T GetPropertyValue<T>(this object sut, string name)
    {
        var field = sut
            .GetType()
            .GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

        return (T)field?.GetValue(sut);
    }
}

Solution 3

No. If you're writing good Unit Tests, you shouldn't need to access any private fields. Unit Tests should test that when passed in a known set of values, a method behaves a certain way (either by returning the appropriate data or using the dependencies in a known fashion).

If you're trying to test the later, use Dependency Injection to inject the dependencies into the class you're testing. You'll have full access to those dependencies for your tests.

Solution 4

Not saying it's a good idea but I've seen InternalsVisibleTo used.

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

Look at this Q. One of the more unpopular answers:

Unit testing and checking private variable value

Solution 5

Testing is about catching defects, and TDD is about catching defects as early as possible. You need about as many test conditions as there is cyclomatic complexity in you code. Complexity beyond a certain amount is difficult to debug; that is why we break complicated tasks into less complicated functions. Some public tasks require a great deal of overall complexity, and that complexity is better managed by dividing it into smaller routines. Now, why would you want to suffer the combinatorial explosion of test conditions all at the higher level function when you could write simpler tests for the lower level functions?

It does not matter if your methods are public or private. The complexity of the method is the most important factor in how likely there is to be a defect in it. You will find and fix defects faster if you only have to test a little bit of complexity at a time.

Say you have broken complicated task A into less complicated tasks X, Y, and Z. If you test only at A, you could find yourself needing X * Y * Z test conditions instead of X + Y + Z conditions.

Share:
10,263
Michelle
Author by

Michelle

Updated on June 04, 2022

Comments

  • Michelle
    Michelle about 2 years

    Is it possible to get access to a private field in a unit test?