单元测试和实体框架

本文关键字:框架 实体 单元测试 | 更新日期: 2023-09-27 18:34:37

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

EF 中的 CRUD 操作,将测试哪些内容?( DbContextSaveChanges() ...需要测试吗?

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

单元测试和实体框架

假设您有 2 层解决方案

我的应用网

我的应用数据

在数据层中,您将拥有如下所示的内容:

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

其中 IProductsRepository 是

public interface IProductsRepository
{
   List<Product> GetAll();
}

在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)
    }
}

谁在运行时将 ProductsRepository 放入构造函数中?人们为此使用像Ninject框架这样的依赖注入。但是为什么?因为这使他们能够伪造产品存储库,就像这样

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

然后像这样对控制器进行单元测试

 [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);
 }

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

如果要测试 ProductsRepository,则不再称为单元测试,因为它依赖于外部源。为了测试这些,你本质上是在测试实体框架。

结合单元测试,人们使用像Specflow这样的框架进行集成测试。从本质上讲,您可以使用真实的产品存储库实例化产品控制器并检查返回的结果。

若要测试

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

前任:

  1. 插入已知数据

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

  3. 断言结果

上述步骤将测试查询和 EF 绑定/模型。

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

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

只需转到此处进行解释,并提供示例。

还可以改为使用内存中数据库测试 EF 模型。下面是使用工作量作为单元测试数据库的示例。