我对EF非常陌生,想知道创建EF和SQL Server数据库的最佳方法。之后我想测试CRUD操作。EF是否以TDD方式实现,我对这些存储库模式、模拟上下文、伪造模式等感到困惑。
在EF中进行CRUD操作时,需要测试哪些内容?(DbContext
,SaveChanges()
需要测试吗?)
那么如何使用Entity Framework进行单元测试呢?(我正在Visual Studio 2012、ASP.NET MVC4中检查所有这些内容)
我对EF非常陌生,想知道创建EF和SQL Server数据库的最佳方法。之后我想测试CRUD操作。EF是否以TDD方式实现,我对这些存储库模式、模拟上下文、伪造模式等感到困惑。
在EF中进行CRUD操作时,需要测试哪些内容?(DbContext
,SaveChanges()
需要测试吗?)
那么如何使用Entity Framework进行单元测试呢?(我正在Visual Studio 2012、ASP.NET MVC4中检查所有这些内容)
假设你有一个两层解决方案:
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)
}
}
谁会在运行时将< strong>ProductsRepository放入构造函数中?人们使用类似< strong>Ninject 框架的依赖注入。但是为什么呢?因为这使它们能够伪造< strong>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并检查返回的结果。