单元测试和实体框架

时间:2013-10-10 04:27:06

标签: c# entity-framework unit-testing asp.net-mvc-4 repository-pattern

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

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

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

4 个答案:

答案 0 :(得分:18)

假设您有2层解决方案

<强> MyApp.Web

<强> MyApp.Data

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

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" } 
           }, 
     }
} 

然后 UNIT TEST 像这样的控制器

 [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 ,并检查返回的结果。

答案 1 :(得分:5)

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

例如:

  1. 插入已知数据

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

  3. 断言结果

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

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

答案 2 :(得分:5)

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

请点击Here获取解释说明。

答案 3 :(得分:2)

您也可以使用内存数据库测试您的EF模型。使用Effort作为单元测试数据库的Here is an example