How to check private fields that change using public methods

Can someone guide me with the proposed method of testing a private field in a class, which is modified using a public method. I read a lot of comments from people suggesting that testing private members is not recommended as they are internal to implement, however this scenario seems to be different from most other answers.

I was thinking of protecting a private field and creating a test subclass that provides the field, but what if I could not change the interiors of the class?

In the example below, an example private member for testing would be _values, which is a record-only collection that receives new values ​​through AddValue ().

public class Sample
{

    private Dictionary<string, string> _values;
    private DateTime _created;

    public Sample()
    {
        _values = new Dictionary<string, string>();
        _created = DateTime.Now;
    }

    public void AddValue(string key, string value)
    {
        _values.Add(key, value);
    }
}
+5
5

, , .

, , , ( _values) AddValue. , .

, , . -, Sample:

public class Sample
{
    private IDictionary<string, string> _values = new Dictionary<string, string>();

    protected virtual IDictionary<string, string> GetDictionary()
    {
        return this._values;
    }

    public void AddValue(string key, string value)
    {
        GetDictionary().Add(key, value);
        //    ^^^
        // notice this!
    }
}

( ), Sample , InitializeDictionary:

// this derived class is only needed in your test project:
internal class SampleTest : Sample
{
    public SampleTest(IDictionary<string, string> dictionaryToUse)
    {
        this._dictionaryToUse = dictionaryToUse;
    }

    private IDictionary<string, string> _dictionaryToUse;

    protected override IDictionary<string, string> GetDictionary()
    {
        return this._dictionaryToUse;
    }
}

SampleTest Sample. , , , , . A unit test AddValue :

[Test]
public void AddValue_addSomething_DictionaryHasOneAdditionalEntry()
{
    var mockDictionary = new Dictionary<string, string>();
    var sample = new SampleTest(mockDictionary);
    var oldCount = mockDictionary.Count;

    sample.AddValue(...);

    Assert.AreEqual(oldCount + 1, mockDictionary.Count);
}

: , . , , , - , .

+2

. . , , Count ( - )

+4

, , _values , , Sample.AddValue, :

private Dictionary<string, string> _values;

internal Dictionary<string, string> _values;

InternalsVisibleTo attribute AssemblyInfo.cs , . _values ​​ .

, "" , , !

+2

, - , . , _values ; AddValue(), /, , . GetKeys() - , . unit test , , .

, unit test - . , Dictionary<> SortedDictionary<> , , . - unit test ; , , unit test, .

+2

, , , , , :

        Type sampleType = sampleInstance.GetType();
        FieldInfo fieldInfo = sampleType.GetField("_values", BindingFlags.Instance, BindingFlags.NonPublic);
        Dictionary<string, string> info = fieldInfo.GetValue(sampleType);
+1

All Articles