使用 Nunit、Ninject、MVC2 和 ADO.Net 实体数据模型进行单元测试
我正在尝试使用 Nunit、Ninject、MVC2 和 ADO.Net 实体数据模型。
假设我有一个 ProductsController 实例化 SqlProductsRepository 类。
public class ProductsRepository : IProductsRepository
{
public MyDbEntities _context;
public ProductsRepository()
{
_context = new MyDbEntities();
}
public IList<Product> GetAllProducts()
{
return (from p in _context.Products select p).ToList();
}
}
public class ProductsController : Controller
{
public ActionResult ProductsList()
{
ProductsRepository r = new ProductsRepository();
var products = r.GetAllProducts();
return View(products);
}
}
我希望能够对 ProductsRepository 执行单元测试,以确保返回正确的数据,但我不确定如何编写测试类。
到目前为止,我读过的每个教程/文档都指向我使用 IProductsRepository 创建模拟对象,然后注入和测试控制器。
在我看来,这似乎绕过了具体的实现。
MyDbEntities 来自 ADO.Net 实体数据模型 .edmx
I'm trying to get my head around using Nunit, Ninject, MVC2 and the ADO.Net Entity Data Model.
Let's say I have have a ProductsController instantiating a SqlProductsRepository class.
public class ProductsRepository : IProductsRepository
{
public MyDbEntities _context;
public ProductsRepository()
{
_context = new MyDbEntities();
}
public IList<Product> GetAllProducts()
{
return (from p in _context.Products select p).ToList();
}
}
public class ProductsController : Controller
{
public ActionResult ProductsList()
{
ProductsRepository r = new ProductsRepository();
var products = r.GetAllProducts();
return View(products);
}
}
I'd like to be able to perform unit testing on ProductsRepository to ensure this is returning the correct data but i'm not sure how to write the Test Class.
Every tutorial/document I've read so far points me to creating a Mock object using IProductsRepository and then injecting and testing the Controller.
This seems, to me, to bypass the concrete implementation.
MyDbEntities comes from an ADO.Net Entity Data Model .edmx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你是完全正确的 - 模拟存储库确实绕过了具体的实现。这就是重点。
单元测试与功能测试不同。您的模拟对象可以设置为返回您明确定义的任何内容,然后您进行测试以确保来自模拟的恒定输入导致预期的结果。
You're exactly right- mocking the repository does bypass the concrete implementation. That's the point.
Unit testing is not the same thing as functional testing. Your mock object can be set up to return whatever you explicitly define, then you test to ensure that constant inputs from your mock lead to expected results.
听起来您想要为 ProductsRepository 创建集成测试而不是单元测试,因为您将针对数据库进行测试,以便您可以检查它是否为您提供了正确的数据。
当对控制器进行单元测试时,您需要模拟 ProductsRepository。
在 ProductsRepository 的集成测试中,我会做一些显而易见的事情,例如
It sounds like you're wanting to create an integration test for ProductsRepository rather than a unit test, since you'd be testing against the database so that you can check it's giving you the right data.
It's when unit testing the Controller that you'd want to mock the ProductsRepository.
In my integration tests for ProductsRepository, I'd be doing the obvious things like
对于两个类(ProductsRepository、ProductsController),您应该有两组测试。每个班级一组测试。
当(单元)测试 ProductsController 时,您应该模拟它的依赖项(在本例中为 IProductsRepository)。绕过依赖项的具体实现是重点。
将有一组完全不同的(集成)测试来验证 ProductsRepository 是否可以访问数据库并返回正确的数据。在这些集成测试中,您不会模拟任何内容,因为您正在测试的是真实存储库与实际数据库之间的交互。
With your two classes (ProductsRepository, ProductsController), you should have two sets of tests. One set of tests for each class.
When (unit) testing the ProductsController, you should mock its dependencies (in this case, the IProductsRepository). Bypassing the concrete implementations of the dependencies is the point.
There will be a completely different set of (integration) tests to validate that the ProductsRepository can hit the database and return correct data. In these integration tests you won't mock anything, since what you're testing is the interaction between a real repository with the actual database.