我正在尝试在当前项目中实现单元测试。之后,我将开始在此项目中进一步使用TDD进行开发。 昨天我开始做一些测试,并不像理论/书籍那样容易。
目前我正在努力解决特定情况,我知道其他人过去也必须与之合作过。
一些背景资料。
我在类Add()
中有一个名为AddProduct
的方法。当新对象传递给Add
方法时,必须首先创建一个新项目,因此我必须首先调用Add()
类的AddItem
方法。
所有这些代码都存在于业务层中。当然,真正的添加发生在DAL中,这是从我的AddProduct
和AddItem
类中调用的。
为了得到一个想法,这是我到目前为止:
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;
}
}
如您所见,我正在AddNewItem
方法中调用Add
。
此示例中的问题是构造函数。 我想要一个带0或1参数的构造函数,如下所示:
public AddProduct() : base(new DataAccess.AddProduct())
{
}
public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal) : base(dal)
{
}
和AddNewItem方法一样(或类似的东西):
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;
}
但是在执行此操作时,AddNewItem
方法中执行的代码使用“真正的”DAL,我不希望在单元测试中使用。我通过向构造函数添加一个新参数解决了这个问题,它也可以为Business.Item
类创建一个模拟DAL。但是,我不认为这是要走的路。
理论上,你可以得到一个带有20个参数的构造函数,所有这些参数都用于单元测试。不是很漂亮。
我的一位同事告诉我,这可能是使用工厂方法设计模式解决的,但他不确定这是否是最佳选择。 因为我从未使用过工厂方法设计模式,所以当单元测试对我来说也不熟悉时,我感觉不太舒服。
我可以尝试其他任何建议吗?
答案 0 :(得分:3)
您可以在这里使用两种方法。
专门设置用于测试的IOC容器。在此容器中,您可以将dal服务配置为测试或模拟DAL服务。
手动连接课程。在这种情况下,您将显式调用AddProduct构造函数并传入测试或模拟DAL服务。
这背后的基本原理是依赖注入允许您创建一个沙箱来隔离和测试代码的特定部分。上面的选项创建了沙箱。