TDD – Touching The Gold
After a long hiatus, we’re coming back to continue our journey into Test-Driven Development (TDD). Over several months, we’ve slowly been writing a ShoppingCart class. Last time, we completed the validation for the ShoppingCart.Add() method. We are ready to start implementing the core behaviour of Add()—The Gold. So far, we’ve been working on managing error conditions—The Thorns. For a refresher on thorns/gold, please see The Thorns and The Gold.
Here is the current state of our ShoppingCart implementation, including the Add() method:
As it stands, Add() is only performing validation.
We are at a stage where we have all the validation we require for Add()—we’re ready to insert items into the ShoppingCart’s Contents collection. Let’s write a simple test to do that:
This unit test sees us trying to add three apples into an instance of our ShoppingCart. But there is a problem: Product does not like our “Apple” descriptor. Let’s check out the definition of Product to see whether we can spot the problem:
Class Product is a mere placeholder. We are using TDD, and until now, that was all we needed from Product. Time to put a description on Product:
Great, our unit test compiles.
But there is a problem; another unit test has a build error:
Luckily, that is an easy fix; we call the Product constructor with a descriptor. It doesn’t matter what the description is since the test is testing for quantities.
All code is building. Let’s run our suite of unit tests. One of them fails:
Our new test, trying to add the three apples, is failing with an InvalidQuantity exception! That’s unexpected—three is a valid quantity! Let’s consult the code for Add():
The last line in Add always throws an InvalidQuantity. With TDD, the implementation code lags behind the unit test code, That is what we have here. We need to implement the invalid quantity conditional:
Let’s rerun our unit test suite. Again our new test fails but this time with a different error:
Fair enough. We’re still not adding anything to the cart’s Contents collection. How do fix this in the quickest, dirtiest way? We add a dummy ShoppingCartItem:
It looks like we cannot call Add() on our Contents collection. That’s because the Contents reference is an IEnumerable<>. IEnumerable<> does not have an Add() method.
We must be able to add to Contents; let’s change the reference to IList<>, which has an Add() method:
We run our unit tests, and they all pass:
If it seems strange that we got our unit test to pass with code that would not pass muster as a production implementation, you’re probably not the only one. Suffice it to say that we have more work to do for this test—and we’ll do that next time.