There is a discount on the Gatsby hair cream
– buy 1 item get 50% discount on next item.
– there is no offer on ‘Bvlgiri soap’.
Let’s implement our IOffer for the discount offer class- DiscountOnNextItemOffer
package com.tdd.shoppingcart; public class DiscountOnNextItemOffer implements IOffer { private double discountPercentage; public DiscountOnNextItemOffer(double discountPercentage) { this.discountPercentage = discountPercentage; } @Override public void applyOffer(Product product) { } // get/set }
Requirement: Apply discount on shopping cart
When: Add 2 unit of ‘Gatsby hair cream’, unit price 30 Rupees.
Then:
– The product count of cart should be 1.
– The total price of product should be 45.
– The total value of cart should be 45.0 rupees.
Add a test for above requirement to the test class.
@Test public void testApplyBuyOneGetFiftyPercentDiscountOnNextOfferToTheCart(){ IOffer offer = new DiscountOnNextItemOffer(50.0); ShoppingCart cart = new ShoppingCart(); cart.setOffer(offer); Product gatsByCream = new Product("Gatsby hair cream", 2, 60.0); cart.addProduct(gatsByCream ); Assert.assertEquals(1, cart.getProductCount()); Assert.assertEquals(45.0, cart.getProductByName("Gatsby hair cream").getTotalPrice(),0.0); Assert.assertEquals(45.0, cart.getTotalCartValue(),0.0); }
The test will have compilation error since we don’t have getProductByname() method in ShoppingCart. Let’s add the method to the ShoppingCart.
public Product getProductByName(String name) { if (productList.size() > 0) { for (Product product : productList) { if (product.getProductName().equals(name)) { return product; } } } return null; }
Now If you run the test, it will fail since we have not added any logic for % discount. Refactor the DiscountOnNextItemOffer class.
package com.tdd.shoppingcart; public class DiscountOnNextItemOffer implements IOffer { private double discountPercentage; public DiscountOnNextItemOffer(double discountPercentage) { this.discountPercentage = discountPercentage; } @Override public void applyOffer(Product product) { int totalQuantity = product.getQuantity(); double unitPrice = product.getTotalPrice() / product.getQuantity(); while (totalQuantity > 1) { double price = product.getTotalPrice(); product.setTotalPrice(price - (unitPrice / (100/discountPercentage))); totalQuantity = totalQuantity - 2; } } // get/set }
Now run the test. It will pass without any problem.
Requirement: Apply discount on shopping cart
When: Add 5 unit of ‘Gatsby hair cream’, unit price 30 Rupees.
Then:
– The product count of cart should be 1.
– The total price of product should be 120.
– The total value of cart should be 120.0 rupees.
Add test for the above requirements.
@Test public void testApplyBuyOneGetFiftyPercentDiscountOnNextOfferToTheMultipleProductsInCart(){ IOffer offer = new DiscountOnNextItemOffer(50.0); ShoppingCart cart = new ShoppingCart(); cart.setOffer(offer); Product gatsByCream = new Product("Gatsby hair cream", 5, 150.0); cart.addProduct(gatsByCream); Assert.assertEquals(1, cart.getProductCount()); Assert.assertEquals(120.0, cart.getProductByName("Gatsby hair cream").getTotalPrice(),0.0); Assert.assertEquals(120.0, cart.getTotalCartValue(),0.0); }
The test will pass without any refactoring.
This is all. Here my aim was to give you a feel of TDD. The presented design may not be optimum and further refactoring may be required. You can keep adding your requirements and follow the cycle- Write failing Test – Write code to make test pass – refactor for the best possible design.
To know more about TDD you can read following books:
Growing Object Oriented Software Guided By Tests
Test Driven Development By Example
Test Driven
Leave a Reply