我发现很难测试EntityFramework 4.我使用数据库第一种方法使用它,现在来得太晚了,转移到poco.Needed提供非常快,没有时间像往常一样正常学习。
我已经使用工作单元实现了存储库模式,但我发现很难将存储库注入我的服务层,这样我就可以测试我的业务层服务的行为,验证等......而无需点击数据库。 但是我遇到了许多小问题。
为了将Repository注入服务(构造函数),调用层需要引用DAL(EF实体)。我不想要这个
如果我有许多存储库EG CustomerRepository,EmployeeRepository,我需要拥有与存储库一样多的构造函数,以便我可以注入存储库。
3.不知道从哪里开始。我没有在网上找到任何使用EF4将存储库注入服务的示例。我看到的所有例子都是自己模拟存储库,这对我来说并不好。
我需要测试我的服务层/ BizLayer而不需要访问数据库。
所有事情都是不可测试的,并且增加了很多依赖性和问题。
我把Noddy的例子放在一起
public class DepartmentServiceLibrary
{
private readonly IDepartmentRepository _departmentRepository;
public DepartmentServiceLibrary(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
return DeparmentBiz.GetDepartments();
}
private DeparmentBL _departmentBiz;
private DeparmentBL DeparmentBiz
{
get
{
return _departmentBiz ?? new DeparmentBL(_departmentRepository);
}
}
}
//内部课程
internal class DeparmentBL
{
private readonly IDepartmentRepository _departmentRepository;
public DeparmentBL(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
using (var ctx = new AdventureWorksContext())
{
var uow = new UnitOfWork(ctx);
_departmentRepository.UnitOfWork = uow;
var query = _departmentRepository.GetAll();
return query.Select(dpt => new DepartmentDto
{
DepartmentId = dpt.DepartmentID,
Name = dpt.Name,
GroupName = dpt.GroupName
}).ToList();
}
}
}
以下TestMethod要求我在dal中添加一个参考点
[TestMethod]
public void Should_be_able_to_call_get_departments()
{
var mock = new Mock<IDepartmentRepository>();
var expectedResult = new List<Department>(); //Dependency to DAL as Department is a EF Entity generated by EF.
mock.Setup(x => x.GetAll()).Returns(expectedResult);
var companyService = new MyCompanyBL(mock.Object); //InternalVisibileTO
var departments = companyService.GetAll();
//assert removed for brevity
那里有任何建议或示例,说明如何做到这一点? 感谢
}
答案 0 :(得分:1)
简短的回答是 - 由于您没有使用POCO,所有图层都会引用您的DAL。
如果没有POCO,您可以使用代码生成,这意味着EF会在Model.edmx.designer.cs文件中创建模型类。
一个选项(尚未尝试过这个 - 在我的脑海中)是将EF实体手动投影到DTO中。
所以你的存储库可能会这样做:
public List<OrderDTO> GetOrdersForCustomer(int customerId)
{
return _ctx.Orders
.Where(x => x.CustomerId == customerId)
.ToList()
.Select(x => new OrderDTO { // left to right copy });
}
OrderDTO类可以位于存储库引用的单独程序集中,也可以位于其他项目中。因此,其他项目将在DTO程序集中运行,并且不需要引用存储库。
但是在这里,你到处都是投入课程(基本上是做POCO,但是手动,还有更多的工作)从左到右复制属性 - 非常痛苦。
然而,这是一个选择。
老实说 - 不需要很长时间就可以转移到POCO。
有一个T4模板可以为您生成POCO - 您可以在几分钟内启动并运行。
既然您已经在使用依赖注入和存储库,那么您应该咬住子弹并更改为POCO,或保留对DAL的引用。