I think this would be an example where dependency injection might help.
What's happening here is that you want to test whether an internal object (the dictionary _values
) was updated correctly by a call to AddValue
. You could achieve this by injecting a mock dictionary into your class-under-test.
This could be done e.g. as follows. First, you'd have to change your Sample
class a little bit:
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!
}
}
This now allows you to replace the default dictionary with another one (which you can observe in your test setup) by deriving from your Sample
class and injecting a mock dictionary by overriding the InitializeDictionary
method:
// 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;
}
}
In your test setup, you can now test this SampleTest
class instead of your Sample
class. This should be OK since the derived class is identical except that it allows you to specify the dictionary it will use internally. A unit test for checking AddValue
could now look like this:
[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);
}
Disclaimer: I'm by no means a unit testing expert, so my example might be flawed or even be way too complicated. My intention was merely to demonstrate that you can test internal properties of a class if you design your class in a reasonably testable way -- e.g. by allowing the means of dependency injection.