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<T>, 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<T> and perform a contains
assertion.  Pretty simple stuff, but it can help keep your tests more
readable.

 

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in c#, mbunit, tdd. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

3 Responses to Effects Of Encapsulation On Unit Tests – EnumerableAssert

  1. Jimmy Bogard says:

    That’s cool, though it still sucks you have to create another list. I wonder why MbUnit requires ICollection?

  2. joeyDotNet says:

    Yeah, but at least with this little wrapper, you never have to create the list in your actual test method.

    I peeked in Reflector on MbUnit and basically the reason their CollectionAssert requires an ICollection is because they’re just newing up an ArrayList (which only takes an ICollection) and calling Contains on it.

  3. Joe Ocampo says:

    I know you knew I had to throw in some BDD flare to your example. LOL

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

    basket.AddItemToBasket(basketItem);

    //EnumerableAssert.Contains(basket.Items, basketItem);
    Specify.That(basket.Items).Contains(basketItem);

    }
    }

    public class EnumerableAssert
    {
    private IEnumerable
    myList;

    public EnumerableAssert(IEnumerable enumerable)
    {
    myList = enumerable;
    }

    public void Contains(T actual)
    {
    CollectionAssert.Contains(new List(myList), actual);
    }
    }

    public class Specify
    {
    public static EnumerableAssert That(IEnumerable enumerable)
    {
    return new EnumerableAssert
    (enumerable);
    }
    }