TDD – Touching The Gold (Part 3)
Last time in our series on TDD, we extended a unit test to ensure that when we called ShoppingCart.Add() with three apples, then three apples ended up in the cart’s Contents collection. So far, so good. However, when we add items to our cart, the checkout cost, i.e. the Total, must also change. That is what we will work on today.
Firstly, let’s refactor ShoppingCart.Add()—the validation details are less relevant in this high-level method; let’s hide them in a private function:
Are our unit tests still passing after our refactoring, or have we broken anything? Let’s run them:
Refactoring complete, let’s return to our 3-apple unit test and extend to test the new Total for a cart containing 3 apples:
But how do we test the Total? How do we get a total cost for the cart? Let’s not worry about a general algorithm. We only need to concern ourselves with the current case of the three apples. That is the beauty of TDD—we’ll work out a general algorithm later on.
With only three apples in the cart, the cost should be the price of an apple times 3.
We need a unit price exposed on the Product class. If each apple costs $0.35 the unit test becomes:
Class Product does not have a unit price on its constructor. Let’s change Product:
Now, let’s check out the unit test. The Product constructor is still showing a build error.
Oops, I forgot to declare the input argument as a decimal (with a lowercase ‘m’). Let’s fix that and also when asserting the Total cost:
We have another test (not shown) that is also failing on instantiating an “Apple” Product without unit price. We remedy the situation by putting in the same unit price ($0.35m).
Finally, when we add the concrete ShoppingCartItem instance into the Contents collection in ShoppingCart.Add(), the unit price on the “Apple” Product is also required:
Let’s fix that:
There are no more compilation errors. What do the unit tests say?
As expected, the 3-apples test is failing since ShoppingCart.Total always returns 0:
Hmm, how shall we fix this most expediently? When ShoppingCart is empty, the Total to $0. Otherwise, we have three apples, and the cost is $1.05 (= 3 * $0.35):
Let’s run the unit test suite:
Nice! All tests pass.
We finish up with one complete unit test and implementation code for three apples costing $0.35 each. Next time we will start generalising so that ShoppingCart.Add() works for any product and quantity.