如何在不使用存储库模式的情况下对 MVC 控制器进行单元测试 ASP.NET

本文关键字:控制器 MVC NET ASP 单元测试 情况下 模式 存储 | 更新日期: 2023-09-27 18:30:42

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

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

这只是为了演示目的。

如何在不使用存储库模式的情况下对 MVC 控制器进行单元测试 ASP.NET

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

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

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

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

在单元测试中,

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

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

这就是

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

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

所以,回到你的案例:

  • 如果你想有可测试的类,你必须注入依赖(db)
  • 应该嘲笑依赖关系
  • 您没有被迫使用存储库模式。如果你可以模拟你的数据库类,那就模拟它。或使用任何其他数据访问抽象