Effects Of Encapsulation On Unit Tests – EnumerableAssert


To keep your classes properly encapsulated, I’ve learned (from others and my

own experience) that it’s usually a good idea to expose collections only as

IEnumerable, until the need arises to elevate it to a higher type.  In

keeping with this, it can sometimes make your unit tests less elegant.  Here are

some examples and a quick little helper that can make things more

readable…

So an extremely simple example would be something like this.

[Test]
public void Should_add_item_to_basket()
{
IBasket basket = new Basket();
IBasketItem basketItem = new BasketItem();

basket.AddItemToBasket(basketItem);

// TODO: Assert that the item was added to the basket
}

 

For reference, here is the IBasket interface:

public interface IBasket
{
IEnumerable<IBasketItem> Items { get; }
void AddItemToBasket(IBasketItem itemToAdd);
}

 

Ok, so of course there are a number of ways we could write this assertion. 

Here are a couple examples using the out of the box MbUnit assertions.

Assert.IsTrue(new List<IBasketItem>(basket.Items).Contains(basketItem));

CollectionAssert.Contains(new List<IBasketItem>(basket.Items), basketItem);

foreach (IBasketItem currentItem in basket.Items) Assert.AreEqual(currentItem, basketItem);

 

Don’t know about you, but those seem a little too verbose to me.  I tend to

like something like this better.

EnumerableAssert.Contains(basket.Items, basketItem);

 

But you won’t find that in the MbUnit framework.  Fortunately it’s easy

enough to write a little wrapper to “hide” the verbosity.

public class EnumerableAssert
{
public static void Contains<T>(IEnumerable<T> enumerable, T actual)
{
CollectionAssert.Contains(new List<T>(enumerable), actual);
}
}

 

Notice all I’m doing is leveraging one of MbUnit’s existing assertions

(CollectionAssert) to wrap an IEnumerable and perform a contains

assertion.  Pretty simple stuff, but it can help keep your tests more

readable.

 

RE: Technology Brainstorm