Shopping Cart – Part 4
Test-Driven Development: write tests before writing code.
Unit testing results in modular code. Modular code is:
- easy to test.
- immune to bugs.
- easy to understand.
- scalable.
Task 1
1. Create a test that fails
Write a unit test named subtotalIsValid
. subtotalIsValid
asserts that the subtotal is calculated correctly.
Inside Cart.java
, write code to make the test fail.
/** * Function name: getSubtotal * @return double * * Inside the function: * 1. return -2 */
2. Make the test pass
Write code inside Cart.java
to make the test pass.
/** * Function name: getSubtotal * @return double * * Inside the function: * 1. loop runs through the size of the ArrayList. * 2. adds the price field of each Item object. * 3. returns the sum */
3. Refactor
Can getSubtotal
be simpler?
- Yes. Run the
ArrayList
through a pipeline of functions:
Intermediate:
mapToDouble
: maps (updates) every element to aDouble
. The lambda expression returns aDouble
value for each element.
Terminal:
sum()
: returns the sum of every element in the sequence.
Important: As you refactor, run the unit test to make sure there are no bugs.
Task 2
1. Create a test that fails
Write a unit test named taxIsValid
. taxIsValid
asserts the tax is calculated correctly.
Inside Cart.java
, write code to make the test fail.
/** * Function name: getTax * @param double (subtotal) * @return double * * Inside the function: * 1. return -2 */
Task 2. Make the test pass
Write code inside Cart.java
to make the test pass.
/** * Function name: getTax * @param double (subtotal) * @return double * * Inside the function: * 1. calculates tax * 2. rounds to two decimal places * 3. returns the result */
3. Refactor
Can getTax
be simpler? Likely not.
Task 3
1. Create a test that fails
Write a unit test named totalIsValid
. totalIsValid
asserts the total is correct.
Inside Cart.java
, write code to make the test fail.
/** * Function name: getTotal * @param double (subtotal) * @param double (tax) * @return (double) * * Inside the function: * 1. returns -2 */
2. Make the test pass
/** * Function name: getTotal * @param double (subtotal) * @param double (tax) * @return (double) * * Inside the function: * 1. returns subtotal + tax */
3. Refactor
Can getTotal
be simpler? Likely not.
Task 4
Define a checkout
method that returns a receipt:
return "\tRECEIPT\n\n" + "\tSubtotal: $" + getSubtotal() + "\n" + "\tTax: $" + getTax(getSubtotal()) + "\n" + "\tTotal: $" + getTotal(getSubtotal(), getTax(getSubtotal())) + "\n";
Final Remarks
Compare your old code to the new code.
Old code: a giant method that performs too many tasks. The method is impossible to unit test and is vulnerable to bugs.
New code: more polished. Each method performs one task (modular) and is easy to test.
Therein lies the beauty of Test Driven Development!