I’m currently trying to cover our shopping cart with unit tests.
Class ShoppingCartItem
has property Term
. It also loads available terms for this item upon object creation. Currently this is done using call to static class in constructor.
Current state:
public class ShoppingCartItem
{
private Dictionary<Guid, ShoppingCartTerm> terms;
public ShoppingCartItem(int productID)
{
terms = SKUInfoGopasProvider.LoadAllTerms(productID);
}
}
My question is. How to make data source interchangeable? Should I introduce factory class?
Obvious answer is use constructor injection but that doesn’t seem somewhat right to me.
I am thinking about making something along these lines.
public class ShoppingCartData
{
private readonly ShoppingCartItemFactory _factory;
public ShoppingCartData(ShoppingCartItemFactory factory)
{
_factory = factory;
}
public void AddItem(int productId)
{
var item = _factory.CreateCartItem(productId);
_items.Add(item);
}
}
2
I think you’re on the right path. The code you posted, however, doesn’t fully reflect that, so I’m going to talk it through here.
The list of Terms
seems to be a dependency of the ShoppingCartItem
class. As such, I’d be tempted to inject it in via the constructor.
The difficulty here is that now any code that used to simply instantiate a ShoppingCartItem
now needs to source the explicit dependencies… meh.
A convenient way to get around this is to use a Factory. The factory (as you’ve shown above) will be responsible for resolving the dependency, passing it into the ShoppingCartItem
constructor, and returning the new ShoppingCartItem
. Done, right?
Well, how does the Factory get a handle of the list of Term
s? This is where I think IoC containers really shine. Your factory can use an IoC container to resolve this dependency on the fly.
This setup should make the ShoppingCartItem
testable, as well as the Factory.