【问题标题】:Coded unit test, database and Dependency Injection编码单元测试、数据库和依赖注入
【发布时间】:2015-09-21 02:47:10
【问题描述】:

我有以下与几乎与数据库逻辑集成的类的代码单元测试相关的问题。例如。我的类方法调用另一个执行数据库查询或存储过程的类。

如果我不想在单元测试期间涉及真实数据库,有哪些选择?

许多人使用接口驱动的方法,在这种方法中我必须声明一个接口。然后在单元测试期间,我将不得不提供一个不能与真实数据库一起使用的接口实现。

我知道在现实世界中我不会有相同接口的各种实现。所以具体的课程对我来说是可以的。 但是为了单元测试而声明一个接口是否可取?

如果我们声明一个接口并使用它编写单元测试,我可能想在测试执行期间决定一个实现,那么我们可能不得不开始考虑 IoC 容器在运行时注入具体类。现在这使应用程序变得不必要的复杂。

如何处理?

【问题讨论】:

  • 我猜这是口味问题。以我的经验,与单元测试的复杂性降低相比,提取接口所需的额外时间是最少的。另见this程序员交流讨论
  • 仅仅因为你引入了一个接口并不意味着你突然需要一个 IoC 容器。 IoC 容器是一种可以帮助简化复杂对象图构建的工具,但在没有容器的情况下始终可以做到这一点。在您的单元测试中,您应该创建小的简单对象图(因为您只测试小单元),您不需要 IoC 容器来创建对象图。只需使用模拟依赖项“新建”被测对象

标签: .net asp.net-mvc entity-framework unit-testing nunit


【解决方案1】:

如果您不想访问数据库,基本上有两种选择:

  • 使用备用数据库,可能是in memory one
  • 通常通过模拟交互来在您自己和数据库之间建立一些分离。

对于大多数模拟框架(所有免费框架)和手动模拟,您需要能够将模拟实例提供给要测试的类。无论您是在模拟一个具体的类还是一个接口,您都必须这样做。这是通过依赖注入完成的。普遍的共识似乎是构造函数注入是首选,尽管如果这对你有用,属性注入也是一种选择。

虽然 IOC 容器可以帮助进行依赖注入,但它们并不是唯一的方法。您可以让您的类客户端在实例化您的类之前创建对象:

public void SomeMethod(string someParam) {
    var db = new SomeDbClass();     // Create db dependency
    var job = new SomeDbClient(db); // Create class that uses db
    job.SomeMethod(someParam);      // call some method...
}

你也可以像这样使用默认的构造函数:

public SomeDbClient(ISomeDependency dependency = null) {
    if(dependency == null) {
       dependency = new SomeDependency();
    }
    _dependency = dependency;
}

您的现有代码无需更改即可支持默认构造函数,但它允许您从测试中注入依赖项的模拟版本。如果您正在转向依赖注入并且不确定是否一直迁移到 IOC 容器,这可能是一个有用的过渡阶段。

注入的依赖可以是一个接口,也可以是一个具体的类,但是如果您希望能够模拟注入类的各个方面,则需要将相关函数声明为虚拟,以便您的模拟可以覆盖行为.

【讨论】:

    【解决方案2】:

    一般情况下您可以这样做,但这取决于您使用的模拟库。对于 Moq,您可以只使用 Setup 方法来模拟方法的结果。通常正如你所说,使用接口是可取的,但你可以在没有接口的情况下这样做:

    c# - How do I mock a class without an interface?

    从架构和松耦合的角度来看,使用接口驱动开发方法是合理的。

    【讨论】:

    • 我同意。但是当我知道接口不会有不同的实现时,仅仅为了单元测试而引入接口和IoC容器等是否正确?为什么要让实际应用变得复杂呢?
    • 对我来说完全没问题。当然这取决于你的方法,所以如果你认为编写接口和处理一些 IoC 容器需要花费太多精力,那么不这样做是可以的,但如果你认为它会为你简化编写单元测试,我相信这是值得的去做吧。
    猜你喜欢
    • 2018-03-03
    • 2021-06-19
    • 1970-01-01
    • 2010-11-30
    • 2017-11-03
    • 2014-10-10
    • 2016-02-16
    相关资源
    最近更新 更多