7

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

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

这仅用于演示目的。

4

3 回答 3

6

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

您的_db字段类型是接口吗?它是通过注射提供的吗?如果是这样,您很可能可以对该方法进行单元测试。

于 2012-04-10T15:07:13.860 回答
5

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

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

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

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

于 2012-04-10T15:08:05.513 回答
2

这就是所谓的testable代码:) 当您执行单元测试时,您需要确定,测试失败的唯一原因是在 SUT(被测系统或被测类)实现中发生变化。当然,当依赖 API 改变时它可能会被破坏(没关系,你应该修改 SUT 以使用新的 API),但如果依赖实现改变,它永远不会失败。这就是使用模拟和存根的原因。

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

所以,回到你的情况:

  • 如果您想拥有可测试的类,则必须注入依赖项(db)
  • 依赖应该被嘲笑
  • 您不必被迫使用存储库模式。如果您可以模拟您的数据库类,只需模拟它。或使用任何其他数据访问抽象
于 2012-04-10T15:12:45.113 回答