Tag-Archive for ◊ Coding kata ◊

Tuesday, March 08th, 2011
The supermarket coding kata problem domain deals with the scenario of pricing goods at supermarkets. The scenario handles situations like.
Items in supermarket have simple prices, e.g. One Gatorade for $4.5. Other items may have complex prices like three for dollar or $3 for one pound etc.
This is the last in the 3 part series of our implementation of the above mentioned problem. We’ll be implementing the checkout list and associated test cases.
The checkout list contains item details with the item and the quantity for each item purchased. The total cost of the checkout list is calculated by aggregating the cost of each item details in the list.
[TestMethod]
public void checkoutlist_contains_of_multiple_itemdetails_for_each_item_and_quantity_of_purchased()
{
    CheckoutList checkoutList = new CheckoutList();
    Item kellogs = new Item(“Kellogs corn flakes”);
    UnitPricingStrategy kellogsPricingStrategy = new UnitPricingStrategy(3.5M);
    kellogs.SetPricingStrategy(kellogsPricingStrategy);
    ItemDetail itemDetail = new ItemDetail(kellogs, 3);
    checkoutList.Add(itemDetail);
    decimal totalPrice = checkoutList.GetTotalPrice();
    Assert.AreEqual(totalPrice, kellogs.GetPrice() * 3);
}
Implementation
public class ItemDetail
{
    private Item _item;
    private int _quantity;
    public ItemDetail(Item item, int quantity)
    {
        this._item = item;
        this._quantity = quantity;
    }
    public decimal GetCost()
    {
        return _item.GetPrice() * _quantity;
    }
}
public class CheckoutList
{
    public CheckoutList()
    {
        _itemDetails = new List<ItemDetail>();
    }
    public void Add(ItemDetail itemDetail)
    {
        _itemDetails.Add(itemDetail);
    }
    List<ItemDetail> _itemDetails;
    public decimal GetTotalPrice()
    {
        decimal totalPrice = 0.0M;
        foreach (var itemDetail in _itemDetails)
            totalPrice += itemDetail.GetCost();
        return totalPrice;
    }
}
Sunday, March 06th, 2011
The supermarket coding kata problem domain deals with the scenario of pricing goods at supermarkets. The scenario handles situations like.
Items in supermarket have simple prices, e.g. One Gatorade for $4.5. Other items may have complex prices like three for dollar or $3 for one pound etc.
In the previous post we’ve implemented the Item class and the tests for testing the functionality of the Item object. We’ll continue working on the sample and now try to implement the different pricing strategies on the items.
·         Create a new class in the test project and name it CountBasedPricingStrategy_Fixture
·         Add the test method to check the functionality of calculating the cost of items that have the pricing strategy based in number of items. E.g. Three for a dollar.
[TestMethod]
public void PricingStrategy_based_on_items_count_should_return_unitprice_based_on_the_parameters_passed()
{
    int itemCount = 3;
    decimal totalPrice = 1.00M;
    PricingStrategy countBasedPricingStrategy = new CountBasedPricingStrategy(itemCount, totalPrice);
    Item item = new Item(“Original Glazed Donuts”);
    item.SetPricingStrategy(countBasedPricingStrategy);
    decimal itemPrice = item.GetPrice();
    decimal expectedPrice = totalPrice / itemCount;
    Assert.AreEqual(expectedPrice, itemPrice);
}
·         As in the previous steps use the refactoring tool to generate the new class and the related methods. Run the test case and watch it fail.
·         Now implement the methods with the required functionality to make this test case pass.
public class CountBasedPricingStrategy : PricingStrategy
{
    private int _itemCount;
    private decimal _totalPrice;
    public CountBasedPricingStrategy(int itemCount, decimal totalPrice)
    {
        this._itemCount = itemCount;
        this._totalPrice = totalPrice;
    }
    public override decimal GetUnitPrice()
    {
        return _totalPrice / _itemCount;
    }
}
public abstract class PricingStrategy
{
    public abstract decimal GetUnitPrice();
}
·         As you can see I have abstracted the pricing calculation strategy to an abstract class and implemented the new class from the abstract class.
·         Similarly we can implement the other pricing strategies as given below.
[TestClass]
public class UnitPricingStrategy_Fixture
{
    [TestMethod]
    public void unit_pricing_strategy_returns_the_unitprice_for_the_item()
    {
        decimal unitPrice = 50M;
        UnitPricingStrategy unitPricingStrategy = new UnitPricingStrategy(unitPrice);
        Item item = new Item(“Kellogs corn flakes”);
        item.SetPricingStrategy(unitPricingStrategy);
        Assert.AreEqual(unitPrice, item.GetPrice());
    }
}
public class UnitPricingStrategy : PricingStrategy
{
    private decimal _unitPrice;
    public UnitPricingStrategy(decimal unitPrice)
    {
        this._unitPrice = unitPrice;
    }
    public override decimal GetUnitPrice()
    {
        return _unitPrice;
    }
}
[TestClass]
public class WeightBasedPricingStrategy_Fixture
{
    [TestMethod]
    public void items_price_should_differ_based_on_the_packed_weight()
    {
        decimal totalPrice = 99.99M;
        decimal baseWeight = 2M;
        decimal packetWeight = .5M;
        PackedWeightPricingStrategy priceWeightPricingStrategy = new PackedWeightPricingStrategy(totalPrice, baseWeight, packetWeight);
        Item item = new Item(“Apple juice 2Ltr”);
        item.SetPricingStrategy(priceWeightPricingStrategy);
        decimal expectedPrice = (totalPrice / baseWeight) * packetWeight;
        Assert.AreEqual(expectedPrice, item.GetPrice());
    }
}
public class PackedWeightPricingStrategy : PricingStrategy
{
    private decimal _totalPrice;
    private decimal _baseWeight;
    private decimal _packetWeight;
    public PackedWeightPricingStrategy(decimal totalPrice, decimal baseWeight, decimal packetWeight)
    {
        this._totalPrice = totalPrice;
        this._baseWeight = baseWeight;
        this._packetWeight = packetWeight;
    }
    public override decimal GetUnitPrice()
    {
        return (_totalPrice / _baseWeight) * _packetWeight;
    }
}
Next we’ll implement the checkout list and complete the first coding kata sample. Till then happy coding…
Sunday, March 06th, 2011
The supermarket coding kata problem domain deals with the scenario of pricing goods at supermarkets. The scenario handles situations like.
Items in supermarket have simple prices, e.g. One Gatorade for $4.5. Other items may have complex prices like three for dollar or $3 for one pound etc.
I have tried to solve the kata using TDD and have recorded the session while attempting to address the situation.
Implementing the Item class
Below are the steps from the TDD session addressing the supermarket coding kata sample:
1.       Create a new visual studio solution and add a test project to it. I have named the project as SupermarketKata.Model.Tests. Add another class library to the solution and name it SupermarketKata.Model.
2.       Add a new unit test to the test project and name it Items_Fixture. This class will contain the test methods for the Item object.
3.       The first test we will be writing on the Item_Fixture will be checking whether every item has a name associated with it. The below test code is used to check this functionality.
[TestClass]
public class Item_Fixture
{
    [TestMethod]
    public void items_should_have_a_name_associated_to_it()
    {
        Item item = new Item(“Apple juice 2Ltr”);
        Assert.AreEqual<string>(item.GetName(), “Apple juice 2Ltr”);
    }   
}
4.       After adding the code to the test method, I have used the Refactor menu item, “Generate new type” to generate the Item class. Similarly the constructor and GetName method is generated using refactoring.
5.       Run the test case and you can see the test case will fail as there is no implementation in the GetName method.
6.       Add the code required to the Item class to make this test pass.
public class Item
{
    public Item(string itemName)
    {
        _name = itemName;
    }
    public string GetName()
    {
        return this._name;
    }
       
    string _name;
}
7.       Run the test again and now you can see it pass.
8.       Next I have used the same approach given above to create the test case for checking whether every item has a unique item number.
[TestMethod]
public void items_should_have_a_unique_itemnumber()
{
    Item item = new Item(“Apple juice 2Ltr”);
    Item item2 = new Item(“Apple juice 1Ltr”);
    Assert.IsFalse(item.GetItemNumber() == item2.GetItemNumber());
}
Code change in the Item class
public class Item
{
    public Item(string itemName)
    {
        _name = itemName;
        GenerateItemNumber();
    }
    private void GenerateItemNumber()
    {
        _itemNumber = Guid.NewGuid().ToString(“N”);
    }
    public string GetName()
    {
        return this._name;
    }
    public string GetItemNumber()
    {
        return _itemNumber;
    }
       
    string _name;
    string _itemNumber;
}
9.       The last test on the item class is to check whether the Total cost of the item is calculated based on the pricing strategy. For this I have mocked the pricing strategy used for calculating the price based on the situation as I haven’t implemented the class yet.
[TestMethod]
public void items_have_a_pricingstrategy_which_is_used_to_calculate_the_unit_price_based_on_pricingstrategy()
{
    var mockedPricingStrategy = new Mock<PricingStrategy>();
    mockedPricingStrategy.Setup((x) => x.GetUnitPrice()).Returns(9M);
    Item item = new Item(“Apple juice 2Ltr”);
    item.SetPricingStrategy(mockedPricingStrategy.Object);
    decimal price = item.GetPrice();
    Assert.AreEqual<decimal>(9M, price);
}
10.   Use the refactoring tool to generate the GetPrice and SetPricingStrategy method on the item class. The final implementation looks like
public class Item
{
    public Item(string itemName)
    {
        _name = itemName;
        GenerateItemNumber();
    }
    private void GenerateItemNumber()
    {
        _itemNumber = Guid.NewGuid().ToString(“N”);
    }
       
    string _name;
    string _itemNumber;
    PricingStrategy _pricingStrategy;
    public string GetName()
    {
        return this._name;
    }
    public string GetItemNumber()
    {
        return _itemNumber;
    }
    public void SetPricingStrategy(PricingStrategy pricingStrategy)
    {
        _pricingStrategy = pricingStrategy;
    }
    public decimal GetPrice()
    {
        return _pricingStrategy.GetUnitPrice();
    }
}
Next we’ll look into the implementation of the pricing strategies and continue our TDD session.