1

I am trying to write a unit test for a method to add or update an IDictionary<string, string>

Here is the my add or update method:

public static class ExtensionMethods
{ 
    public static void AddOrUpdate(IDictionary<string, string> Dictionary, string 
                                                                     Key, string Value)
    {
        if(Dictionary.Contains(Key)
        {
            Dictionary[Key] = Value;
        }
        else
        {
            Dictionary.Add(Key, Value);
        }
    }
}

Here is my unit test:

[TestMethod]
public void Checking_Dictionary_Is_Able_To_Update()
{
    // Arrange
    IDictionary inputDictionary = new Dictionary<string, string>();

    inputDictionary.Add("key1", "someValueForKey1");
    inputDictionary.Add("key2", "someValueForKey2");
    string inputKeyValue = "key1";
    string dataToUpdate = "updatedValueForKey1";


    // Act
    // The following method call produces a conversion error
    ExtensionMethods.AddOrUpdate(inputDictionary, inputKeyValue, dataToUpdate);
}

The error that I am getting when I call the AddOrUpdate() is that I cannot convert a System.Collections.IDictionary to a System.Collections.Generic.IDictionary string, string

Can anyone point out what I might be doing wrong.

Luke
  • 43
  • 5
  • The problem is the IDictionary class, the one inside your test method is of type System.Collections.IDictionary while the one in your AddOrUpdate method it is System.Collections.Generic.IDictionary type. Check your using statements or use fully qualified types. Local parameters are usually lower cased to make them easily recoginsable from other public members of the class. The question isn't really about unit testing, it's more about why AddOrUpdate() method throws. – pijemcolu Jun 27 '17 at 13:45

1 Answers1

2

Arrange is setting the test subject to the wrong type IDictionary while the method under test expects IDictionary<string, string>

// Arrange
IDictionary<string, string> inputDictionary = new Dictionary<string, string>();
//...code removed for brevity.

or you can even use var

// Arrange
var inputDictionary = new Dictionary<string, string>();
//...code removed for brevity.

Next the method under test is calling the wrong method to check if key is contained in collection.

public static void AddOrUpdate(this IDictionary<string, string> Dictionary, string Key, string Value) {
    if (Dictionary.ContainsKey(Key)) { //<-- NOTE ContainsKey
        Dictionary[Key] = Value;
    } else {
        Dictionary.Add(Key, Value);
    }
}

The Extension method can be improved to make it more generic...

public static class ExtensionMethods {
    public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> Dictionary, TKey Key, TValue Value) {
        if (Dictionary.ContainsKey(Key)) {
            Dictionary[Key] = Value;
        } else {
            Dictionary.Add(Key, Value);
        }
    }
}

Which allow it to be used with any IDictionary<TKey,TValue> derived type and called..

[TestMethod]
public void _Checking_Dictionary_Is_Able_To_Update() {
    // Arrange
    var inputDictionary = new Dictionary<string, string>();

    inputDictionary.Add("key1", "someValueForKey1");
    inputDictionary.Add("key2", "someValueForKey2");
    string inputKeyValue = "key1";
    string dataToUpdate = "updatedValueForKey1";


    // Act
    inputDictionary.AddOrUpdate(inputKeyValue, dataToUpdate);

    // Assert
    //...
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472