TDD By Example

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.
TDD-By-Example17

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

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of