NUnit Mock with WinForms Code Review

Define the DataAccess Interface and Handler Object

Code Download

Code Review

Code Walkthrough

* Based on NUnit version 2.4.8

Define the IShoppingDataAccess interface, which defines any actions that can be performed by the application classes.

public interface IShoppingDataAccess { String GetProductName(Int32 productID); Int32 GetUnitPrice(Int32 productID); List<BasketItem> LoadBasketItems(Guid basketID); void SaveBasketItems(Guid basketID, List<BasketItem> basketItems); }

These actions will usually involve querying or updating one or more databases.

Define the DataAccessProvider class, which inherits from the IShoppingDataAccess interface, and defines the relevant data access methods.

class DataAccessProvider : IShoppingDataAccess { public string GetProductName(int productID) { return (DataStoreAccessor.FindProductNameByProductID(productID)); } public int GetUnitPrice(int productID) { return (DataStoreAccessor.FindUnitPriceByProductID(productID)); } public List<BasketItem> LoadBasketItems(Guid basketID) { return(DataStoreAccessor.RetrieveItemsByBasketID(basketID)); } public void SaveBasketItems(Guid basketID, List<BasketItem> basketItems) { DataStoreAccessor.SaveItemsByBasketID(basketID, basketItems); } }

Define the DataStoreAccessor class, which is simply a static class which is used as a substitue for an actual database.

static class DataStoreAccessor { private static Dictionary<Guid, List<BasketItem>> m_savedBasket = new Dictionary<Guid, List<BasketItem>>();
public static String FindProductNameByProductID(Int32 productID) { String productName = String.Empty;
switch (productID) { case 1: productName = "The Moon"; break;
case 5: productName = "Love"; break; } return (productName); } public static Int32 FindUnitPriceByProductID(Int32 productID) { Int32 unitPrice = Int32.MinValue;
switch (productID) { case 1: unitPrice = 99; break;
case 5: unitPrice = 47; break; } return (unitPrice); } public static List<BasketItem> RetrieveItemsByBasketID(Guid basketID) { return (m_savedBasket[basketID]); } public static void SaveItemsByBasketID(Guid basketID, List<BasketItem> basketItems) { List<BasketItem> tmpList = new List<BasketItem>(); tmpList.AddRange(basketItems);
if (m_savedBasket.ContainsKey(basketID)) { m_savedBasket.Clear(); } m_savedBasket.Add(basketID, tmpList); } }

The point of this class is to return "hard-coded" data based on certain class method calls. Using this class also means the application can run without needing to connect to a database data source.

In reality, this class would not be required and all method calls in the DataAccessProvider class would connect to a database directly and the results persisted from the database itself.

This class is only used when running the application normally. When running the unit tests and mocking objects, this class will not be invoked.