TDD – Invalid ShoppingCart Quantity (Part 2)
TDD – Invalid ShoppingCart
Quantity (Part 2)
In Part 1, we started writing the validation for an invalid quantity
argument being passed into the Add()
method of our ShoppingCart
class. We used TDD to drive us to write the implementation code for Add()
. Here is the last test that we turned green (i.e. made pass):
This test is specific; it is only covering us for a quantity
of -2. However, we know that all negative quantities supplied to ShoppingCart.Add()
should trigger a validation failure.
What are we to do?
OK, how about we provide another invalid quantity data point, say -5? Yes, that should result in the same InvalidQuantity
exception. The only difference should be a variation of the error message: ‘-5 is not a valid quantity.‘
Before we go there, let’s refactor our test to allow us to supply several invalid values for the quantity
parameter. We turn it into a parameterised test:
In this unit testing harness, the [Theory]
attribute parameterises a test. The [InlineData]
attribute holds the value, here -2, passed into the test parameter, i.e. quantity
.
We have refactored the test. Does it still work as before? Let’s run our tests and find out:
All of our test pass. We haven’t broken anything. The tests act as a safety net, helping us preserve the behaviour of the code.
We’ll now add another InlineData
attribute with a value of -5, thereby adding a test for this quantity.
What happens when we run the tests now?
We get a test failure:
Fair enough. Let’s remember that the InvalidQuantity
exception is outputting a hard-coded error message:
In its current state, InvalidQuantity
‘s error message can never be ‘-5 is not a valid quantity.‘
Let’s fix this. We make the error message dynamic by passing the quantity
parameter into the constructor:
That’s better. Although now we have a compilation error in Add()
:
No surprise there. We’ve added a constructor parameter to InvalidQuantity
yet are creating a new instance without passing quantity
. Let’s fix that too:
Good. I think we’re done. What do the tests say?
The tests are all passing. Great!
For the sake of completeness, I like to add a few more data points to my tests. Therefore, I’ve added two additional invalid quantities to our test, -300 and -1000:
If we’ve done a decent job, these additional tests should pass:
The tests pass.
We’ve made our implementation code function generically using TDD. Adding more tests with different test data forced us to parameterise our implementation code.
Or, in the master programmer’s own words:
“As the tests get more specific,
the code gets more generic.”
– Uncle Bob
Next time we’ll wrap up the validation of invalid quantities. At the moment, we throw ZeroQuantity
and InvalidQuantity
exceptions. Do we need two exception types for essentially the same condition? Can we refactor and simplify? You’ll find out tomorrow.
Leave a Reply
Want to join the discussion?Feel free to contribute!