Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing Add/Get method pairs

I am a .Net developer coding in C#, and I have been assigned to a project that its manager wants it to be thoroughly unit tested, mostly emphasising isolation so that one logical bug ideally fails one test, and there are no dependencies between tests.

Today we are discussing testing patterns, and the following question has arised:

Lets say we have an object named MyHashTable, that implements:

void Add(string key, string value);

string GetValue(string key);

We want to test each of those methods independently. The main problem of course, logically we can't get what we never added, and we can't verify something was added without getting it. We have heard and read about stubbing/mocking and other techniques that might help overcome this issues, but can't decide which solution would be most readable and maintanable.

Therefore I ask for advices/ideas how to test those methods in isolation, and if you may, include pros and cons for your suggestion. Thank you!

like image 662
Eldar S Avatar asked Mar 02 '12 08:03

Eldar S


1 Answers

If you want to achieve full independence and isolation, then you'll most likely have to expose some internals of MyHashTable. For example, underlying collection that Add adds elements to:

public class MyHashTable<TKey, TValue>
{
    internal Dictionary<TKey, TValue> Storage { get; set; }
    // ...
}

This isn't very pretty as you can see, but like I said, it's not possible to test those two methods in full isolation without exposing something (like you noticed, it's a method pair). You can naturally provide other ways to initialize your class, eg. with constructor taking collection, but it only delegates problem one step further - you'll need to verify that constructor worked as well, and you'll probably need Get method for that... which brings you back to original problem.

Edit:

Note that I'm not suggesting revealing internals/implementation details as the only path to follow. You can simply test those methods together (not as in single test, but one utilizing other), which might prove to be better solution. Sure - if your Add at some point fails, Get tests will fail too. But then again, you want to fix broken Add - once that's done everything is back to normal. Problem naturally lies in how do you distinguish whether it was Add or Get that got broken - but that's where proper assertion failure messages or guard assertions concept I linked in comment come in handy.

Truth is, sometimes full separation and isolation is way too difficult to achieve or simply would need you to introduce poor design. That's one of the reasons they should never be final goal.

like image 103
k.m Avatar answered Oct 26 '22 13:10

k.m