One of the validations we have already covered for the Add() method on our ShoppingCart class is that of adding zero quantity of a product. Zero is not the only invalid quantity. What other amounts don’t make much sense? How about negative quantities? Putting -3 punnets of strawberries into our ShoppingCart is non-sense. Let’s consider negative quantities as invalid input.
We’re using TDD, so we’ll first write the test for a negative quantity scenario:
OK, our InvalidQuantity exception is new; the compiler pulls us up for that. Fair enough. Let create the smallest possible definition of InvalidQuantity:
Alright! Our new unit test compiles!
Here is the current definition of ShoppingCart.Add():
As it stands, it doesn’t throw an InvalidQuantity exception. Therefore our new unit test should fail:
OK, the test is failing. What do we need to do to make it pass?
Here is the current definition of Add() again:
Add() must throw an InvalidQuantity exception. However, Add() always throws a ZeroQuantity exception! We are now at the point where we need to specify a condition for throwing a ZeroQuantity exception.
When using TDD, I find myself writing implementation code that lags by exactly one test. We are experiencing the same phenomenon here.
Let’s qualify the throwing of the ZeroQuantity exception and then (always) throw an InvalidQuantity exception:
When we run our test harness, all the tests pass!
So far, so good. To finish up, let’s give the InvalidQuantity exception an error message. As usual, we must have a test first. We modify our unit test to check for the presence of an error message:
As expected, the test now fails.
OK, what is the simplest possible way for us to get this exact error message from InvalidQuantity? We hard-code it:
The tests pass!
But we did a bad thing here, right? Hard-coding is bad, No? It seems so wrong to hard-code an error string specifying an invalid quantity of -2. Surely, when ShoppingCart.Add() is called in a program, the quantity argument could be any negative integer! Yes, of course, it could.
However, our unit test only drives us to return this precise error message. As per Rule 3 of the Three Rules of TDD, this is all we are allowed to implement:
Rule 3: Only write enough production code to make the failing test pass.
We do not yet have tests that require us to parameterise the invalid quantity – we will write those next time.
TDD – Invalid ShoppingCart Quantity
/by Olaf ThielkeTDD – Invalid
ShoppingCart
QuantityPhoto by David Clarke on Unsplash
One of the validations we have already covered for the
Add()
method on ourShoppingCart
class is that of adding zero quantity of a product. Zero is not the only invalid quantity. What other amounts don’t make much sense? How about negative quantities? Putting -3 punnets of strawberries into ourShoppingCart
is non-sense. Let’s consider negative quantities as invalid input.We’re using TDD, so we’ll first write the test for a negative quantity scenario:
OK, our
InvalidQuantity
exception is new; the compiler pulls us up for that. Fair enough. Let create the smallest possible definition ofInvalidQuantity
:Alright! Our new unit test compiles!
Here is the current definition of
ShoppingCart.Add()
:As it stands, it doesn’t throw an
InvalidQuantity
exception. Therefore our new unit test should fail:OK, the test is failing. What do we need to do to make it pass?
Here is the current definition of
Add()
again:Add()
must throw anInvalidQuantity
exception. However,Add()
always throws aZeroQuantity
exception! We are now at the point where we need to specify a condition for throwing aZeroQuantity
exception.When using TDD, I find myself writing implementation code that lags by exactly one test. We are experiencing the same phenomenon here.
Let’s qualify the throwing of the
ZeroQuantity
exception and then (always) throw anInvalidQuantity
exception:When we run our test harness, all the tests pass!
So far, so good. To finish up, let’s give the
InvalidQuantity
exception an error message. As usual, we must have a test first. We modify our unit test to check for the presence of an error message:As expected, the test now fails.
OK, what is the simplest possible way for us to get this exact error message from
InvalidQuantity
? We hard-code it:The tests pass!
But we did a bad thing here, right? Hard-coding is bad, No? It seems so wrong to hard-code an error string specifying an invalid quantity of -2. Surely, when
ShoppingCart.Add()
is called in a program, the quantity argument could be any negative integer! Yes, of course, it could.However, our unit test only drives us to return this precise error message. As per Rule 3 of the Three Rules of TDD, this is all we are allowed to implement:
We do not yet have tests that require us to parameterise the invalid quantity – we will write those next time.