我几周来一直在研究这个话题。我发现了很多材料,但我觉得完全无法回答这个问题。许多信息已有多年历史,可能不适用。
我正在构建一个MVC4应用程序,它是对现有但过时的应用程序的重建。数据库已经存在(因此数据库优先方法)很大且很复杂。理想情况下我想要的是一个虚假的“实体”对象,它与我的主要实体对象相同,但使用了某种不同的“模拟”或内存数据库,这样我就可以生成一堆虚假数据,运行测试和收到反馈。例如:
FakeEntities _db = new FakeEntities();
// test a controller action
据我所知,到目前为止我应该使用integration testing。根据{{3}}集成测试意味着测试控制器操作并意味着LINQ到实体和LINQ到对象的问题更少
如果您模拟存储库,您将使用Linq-To-Objects,您将进行绿色测试,但如果您使用Linq-To-Entities运行应用程序,您将获得异常
我知道他的意思,我可以同意 - 我想确保我总是使用Linq-To-Entities和一个真实的(或接近真实的)数据库。
我已经阅读了很多关于this post by Ladislav Mrnka和repository pattern看起来非常接近我可能尝试的内容。事实上,我已经创建了一个虚拟项目,在其中我测试了创建this blog by linush并成功使用了Entity Framework和一个依赖于内存中ObjectSet的“模拟”DbContext。
我对这种方法的问题是
答案 0 :(得分:1)
我写了两篇关于如何在LINQ和Entity Framework中使用Unit Of Work
和Repository Pattern
的文章。这是测试/模拟的好方法。看看他们。
http://gaui.is/how-to-mock-the-datacontext-entity-framework/
答案 1 :(得分:1)
你的问题本身就充满了矛盾。例如,您说测试存储过程很重要,但您也希望与数据库无关。它是哪一个?
如果您确实希望与数据库无关,请删除存储过程并使测试环境更加简单。您将能够使用完全内存数据库(如Apache Derby)作为测试环境的一部分。这使得在Jenkins内部或任何CI环境中编写脚本变得更容易。
接下来,你需要决定你想要测试什么。如果要围绕控制器包装单元测试,请确保将控制器编写为可测试。既然你从头开始,这应该很容易做到。使用注入等概念可以轻松地将部分功能交换出来用于模拟实现。使用模拟对象框架(如您所发现的)创建一组对象,并将这些对象传递给正在测试的控制器。
如果你可以自己测试你的控制器,那么以上所有都是好的。但是,如果您正在构建一个高度相互依赖的堆栈,数据库存储过程与控制器和视图进行深入交互,那么这将无法正常工作。重新设计您的方法,以便可以进行单元测试或转向功能测试。
Selenium是Web应用程序中最着名和最常用的功能测试环境之一。您可以从头到尾测试整个系统。更好的是,您可以开始围绕现有的旧应用程序编写Selenium测试,然后确保新实现在重写期间重现相同的功能。