2010-12-13 47 views
2

我发现很难测试EntityFramework 4。我使用它使用数据库的第一种方法,现在太晚,以移动到poco.Needed交付相当快,没时间照常学习。EF4存储库模式问题注入存储库到服务。似乎没有得到它的权利

我已经实现了存储库模式与工作单元,但我发现很难注入一个存储库到我的服务层,以便我可以测试我的业务层服务,验证等行为...没有击中数据库。 但我在许多小问题上招致。

  1. 为了将Repository注入服务(构造函数),调用层需要引用DAL(EF实体)。我不想这

  2. 如果我有很多存储库EG CustomerRepository,EmployeeRepository比我需要有多少构造函数作为存储库,以便我可以注入存储库。

    3.不确定该从哪里出发。我没有在网上找到任何使用EF4将资源库注入服务的例子。我见过的所有例子都是嘲笑自己的存储库,这对我并不好。

我需要测试我的服务层/ BizLayer没有击中数据库。

所有的事情都是不可测试的,并增加了这么多的依赖和问题。

诺迪比如我已经把

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 

任何建议或例子显示如何做到这一点? 感谢

} 

回答

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的引用。在代码方面类似

+0

发现只是证实了我的fears.Do我需要学习t4.Everything我做我必须能够解释。我会给它一个 – user9969 2010-12-13 10:44:12

+0

随着poco我想你转向代码生成和使用t4 templates.How有关存储过程,复杂类型等。如何处理它们在poco.Do你产生它们? – user9969 2010-12-13 10:56:04

+0

@ user231465 - 这里是T4 POCO Generator:http://visualstudiogallery.msdn.microsoft.com/en-us/23df0450-5677-4926-96cc-173d02752313。你不需要“学习”T4本身。只需安装它,让它生成您的POCO - 并将生成的POCO移到单独的程序集。 – RPM1984 2010-12-13 11:08:04