10

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

EF 中的 CRUD 操作,会测试什么?( DbContext, SaveChanges()... 需要测试吗?)

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

4

4 回答 4

18

假设您有 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框架这样的依赖注入。但为什么?因为这使他们能够伪造ProductsRepository并喜欢这样

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则不再称为单元测试,因为它依赖于外部源。要测试这些,您实际上是在测试 Entityframework。

结合单元测试,人们使用 Specflow 等框架进行集成测试。本质上,您可以使用真实的ProductsRepository 实例化 Productscontroller检查返回的结果。

于 2013-10-16T23:07:01.330 回答
5

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

只需到此处使用示例进行解释即可。

于 2013-10-15T13:46:47.410 回答
5

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

前任:

  1. 插入已知数据

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

  3. 断言结果

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

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

于 2013-10-10T04:35:22.137 回答
2

您也可以改为使用内存数据库测试您的 EF 模型。这是使用 Effort 作为单元测试数据库的示例。

于 2013-10-15T12:09:33.903 回答