2012-04-10 59 views
7

我只是想知道是否有一种方法可以在不使用存储库模式的情况下单元测试我的一些控制器Action中的 MVC。我开发了一个ASP.NET MVC网站,但是在初始阶段没有进行单元测试。现在我想演示一些单元测试给我的导师使用可能是两个或更多的操作在我的控制器。我的大部分行为逻辑从数据库获取数据,一个控制器从不同的表中获取数据,即一个控制器中的动作从不同的表中读取。我认为这可以使用Generic Repository模式进行测试。作为初学者,我发现我只能单元测试一个不是来自数据库的代码,但不幸的是,我的控制器中的大部分代码Actions都来自数据库。我在Visual Studio中使用默认的测试工具,并在我的数据库中使用EF代码优先方法。
例如,我想单元测试下面的动作,而不必单元测试同一控制器中的其他动作。如何在不使用存储库模式的情况下单元测试ASP.NET MVC控制器

public ActionResult Index() 
    { 
     var model = _db.PhotoGallery; 
     return View(model); 
    } 

这只是为了演示目的。

回答

6

根据定义,单元测试只应该影响它调用的方法。如果您可以找到一种方法来模拟您的_db对象,以便实际上不会导致数据库往返,那么您可以对依赖它的此方法进行单元测试。否则,不。

您的_db字段的类型是一个接口吗?它是通过注射提供的吗?如果是这样,那么你可以单元测试这种方法。

5

如果不在您的控制器方法中删除对数据库的直接依赖关系,您将无法单元测试这些方法。

这样做的总体推荐方式是将IOC容器(例如Ninject)与MVC结合使用,它允许您将需要的数据传递给控制器​​的构造函数。这个“数据对象”不能绑定到数据库,通常它不是只是一个POCO对象,就是作为一个接口传递。

在您的单元测试中,您可以使用为单元测试构建的内存数据对象替换这些依赖项,通常使用模拟框架(例如Rhino Mocks或Moq)“模拟”。

使用这种方法,您不仅可以让您的控制器进行单元测试,而且最终还会得到非常松散的代码,这可能会为以后的开发带来好处。

2

这就是所谓的testable代码:) 当您执行单元测试时,您需要确保在SUT​​(被测系统或正在测试的类)实现中只有失败测试的原因发生变化。当然,当依赖性API改变时它可能会被破坏(那好,你应该修改SUT来使用新的API),但是如果依赖性实现改变它永远不会失败。这就是为什么使用嘲笑和存根。

但是,如果你想模拟依赖,你不应该在SUT中创建它。它应该注入SUT(构造函数,参数注入的属性)。

所以,回到你的情况:

  • 如果你想有可测试的类,你必须注入依赖(DB)
  • 依赖应该被嘲笑
  • 你并不一定要使用存储库模式。如果你可以模拟你的db类,只是嘲笑它。或者使用任何其他数据访问抽象
相关问题