I'm trying to implement unit tests in my current project. After that I'll start developing using TDD further on in this project. Yesterday I started making some tests and it wasn't as easy as it looks in theory/books.
At the moment I'm struggling with a specific scenario, which I know someone else must have worked with in the past also.
Some background information.
I've got a method called Add()
in the class AddProduct
. When a new object is passed to the Add
method, there has to be made a new Item first, so I'll have to call the Add()
method of the AddItem
class first.
All of this code exists in the Business Layer. Off-course the real adding happens in the DAL, which is called from within my AddProduct
and AddItem
classes.
To get an idea, this is what I have so far:
public class AddProduct : Product<IDataAccessAdd<Entities.Product>>, IBusinessAdd<Entities.Product>
{
private readonly Business.IBusinessAdd<Entities.Item> _addItem;
public AddProduct() : base(new DataAccess.AddProduct())
{
_addItem = new AddItem();
}
public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal, Business.IBusinessAdd<Entities.Item> itemBl) : base(dal)
{
_addItem = itemBl;
}
private Entities.Product _newProduct;
public bool Add(ref Product product, string user)
{
bool isAdded = false;
_newProduct = product;
if(AddNewItem(user))
{
isAdded = Dal.Add(product);
}
return isAdded;
}
private bool AddNewItem(string user)
{
var newItem = new Item();
bool isAdded = _addItem.Add(ref newItem, user);
_newProduct.Item = newItem;
return isAdded;
}
}
As you can see, I'm calling the AddNewItem
from within the Add
method.
The problem in this example is the constructor. I'd like to have a constructor with 0 or 1 parameter, like so:
public AddProduct() : base(new DataAccess.AddProduct())
{
}
public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal) : base(dal)
{
}
and the AddNewItem method like so (or something similar):
private bool AddNewItem(string user)
{
var newItem = new Item();
var addItem = new Business.AddItem();
bool isAdded = addItem.Add(ref newItem, user);
_newProduct.Item = newItem;
return isAdded;
}
But when doing this, the code executed in the AddNewItem
method uses a 'real' DAL and I don't want that in a unit test. I solved this issue by adding a new parameter to the constructor, which can also create a mock DAL for the Business.Item
class. However, I don't think this is the way to go.
In theory, you could get a constructor with 20 parameters, all used for unit testing. Not a very pretty sight.
A colleague of mine told me this could probably be solved using a Factory Method design pattern, but he wasn't sure that would be a best choice. As I've never worked with the Factory Method design pattern, I don't feel very comfortable implementing it when unit testing is new to me also.
Any other suggestions which I could try?