单元测试和实体框架

nee*_*eel 10 c# unit-testing entity-framework repository-pattern asp.net-mvc-4

我是EF的新手,我想知道用SQL Server数据库创建EF的最佳方法是什么.之后我想测试CRUD操作.EF是以TDD方式实现的,我对这些存储库模式,模拟上下文,假模式等感到困惑.

EF中的CRUD操作,会测试所有内容吗?(DbContext,SaveChanges()......需要测试吗?)

那么任何想法如何使用基于Entity Framework的组件进行单元测试?(我在Visual Studio 2012,ASP.NET MVC4中检查所有这些)

sun*_*nil 18

让我们说你有2层解决方案

MyApp.Web

MyApp.Data

在您的数据层中,您将拥有以下内容:

public class ProductsRepository : IProductsRepository
{
     public List<Product> GetAll()
     {
        //EF stuff 
        return _dbcontext.Products;
     }
} 
Run Code Online (Sandbox Code Playgroud)

其中IProductsRepository是

public interface IProductsRepository
{
   List<Product> GetAll();
}
Run Code Online (Sandbox Code Playgroud)

在MyApp.Web中,趋势是这样做.

public class ProductsController : Controller
{
    private readonly IProductsRepository _productsRepository;
    public ProductsController(IProductsRepository productsRepository)
    {
        _productsRepository = productsRepository;
    }

    public ActionResult Index(int page=1)
    {
        var allProducts = _productsRepository.GetAll();

        return View(allProducts)
    }
}
Run Code Online (Sandbox Code Playgroud)

谁在运行时将ProductsRepository放入构造函数中?人们使用像Ninject框架这样的依赖注入.但为什么?因为这使他们能够伪装ProductsRepository并像这样

public class FakeProductsRepository : IProductsRepository
{
     public List<Product> GetAll()
     {
        return new List<Product> 
           { 
              new Product { Name = "PASTE" }
              new Product { Name = "BRUSH" } 
           }, 
     }
} 
Run Code Online (Sandbox Code Playgroud)

然后单元测试这样的控制器

 [TestMethod]
 public void IndexGetsAllProducts()
 {
        //Arrange 
        var fakeProductRepo = new FakeProductsRepository();
        var productsController = new ProductsController(fakeProductRepo);

        //Act
        var result = productsController.Index(1) as ViewResult;

        //Assert
        var model = result.Model as List<Product>;
        Assert.AreEqual(2, model.Count);
 }
Run Code Online (Sandbox Code Playgroud)

基本上,您伪造数据库,因此单元测试快速且独立于数据库.有时为伪造人们使用像Moq这样的模拟框架,它基本上做同样的事情.

如果要测试ProductsRepository,则不再将其称为单元测试,因为它依赖于外部源.要测试那些你实际上是在测试Entityframework.

结合单元测试,人们使用Specflow等框架进行集成测试.从本质上讲,你可以实例化的ProductsController与真实ProductsRepository并检查结果回来.


TGH*_*TGH 5

要测试EF功能,我建议针对已知数据编写集成测试.一种常见的方法是将数据构建为测试的一部分,作为测试基于选择的功能的前提条件:

例如:

  1. 插入已知数据

  2. 针对已知数据运行选择功能

  3. 断言结果

以上步骤将测试您的查询和EF绑定/模型.

作用于从EF返回的数据的业务逻辑应该通过模拟来抽象EF逻辑.这将使您能够编写单元测试,只测试逻辑而不必担心集成点/数据依赖性.


Thi*_*a H 5

存储库和工作单元模块旨在在数据访问层和应用程序的业务逻辑层之间创建抽象层.实现这些模式有助于将应用程序与数据存储中的更改隔离开来,并可以促进自动化单元测试或测试驱动开发(TDD).

请到这里进行解释,例如.