代码之家  ›  专栏  ›  技术社区  ›  Wesley Hill

将依赖项注入测试

  •  7
  • Wesley Hill  · 技术社区  · 15 年前

    通常在使用依赖注入时,单元(和其他)测试负责创建/模拟被测系统的依赖项并注入它们。

    然而,有时候测试本身有依赖性,或者需要将依赖性注入到它自己无法创建的SUT中。例如,当测试与数据库交互的类时,测试需要知道连接字符串和目录名等,因为它们不一定对运行测试的每个人都是相同的,所以不能硬编码。

    那么,您如何建议测试找出这些设置?一些XUnit风格的测试框架是否提供了一种将依赖性赋予测试夹具的方法?在运行所有测试之前,测试类是否应该具有填充的静态属性?测试是否应该忽略DI实践并从某个全局位置获取依赖关系?其他建议?

    3 回复  |  直到 15 年前
        1
  •  1
  •   S.Lott    15 年前

    当您使用单元测试框架进行集成测试时,您实际上没有DI或单元测试问题。

    您拥有的是利用高性能单元测试框架的集成测试。

    因为它们是集成测试,所以它们在种类上与单元测试不同。“独立性”不再重要了。

    获取不同用户的集成测试设置的最佳方法是以最终应用程序获取它们的相同方式获取它们。如果你在Java中工作,你可能会有一个属性文件。在python中,我们有用于集成测试的特殊django设置文件。

        2
  •  3
  •   Mark Seemann    15 年前

    有一个原则 全自动测试 :您应该能够从源代码管理存储库中下拉所有源代码,并且只需运行测试。

    鉴于环境(机器)具有正确的安装基础(即编译器、测试框架、数据库引擎(如果相关),测试负责在执行测试用例之前设置它们的夹具。

    这意味着对于数据库,测试应该

    1. 创建相关数据库
    2. 运行测试
    3. 在最后一个测试用例之后再次删除数据库

    如果由于某种原因您不能这样做,那么您真正能做的唯一一件事就是在源代码管理系统中有一个配置文件,其中包含测试环境中所有计算机的特定于计算机的条目;例如,对于计算机 TST1 连接字符串是一个值,但用于 TST2 这是另外一个。

    这会很快变得很难看,所以让测试负责夹具的设置和拆卸要容易得多,因为这意味着它们可以简单地使用硬编码的值,或者现场生成的值。

    这真的和狄无关…

        3
  •  1
  •   S.Lott    15 年前

    DI与依赖复杂性作斗争,而您的单元测试大多数时候必须非常简单。典型的单元测试将检查一个隔离类的一个隔离方面。而不是它的所有依赖项,您创建模拟并(通常)通过CUT(测试中的类)构造函数注入它们。这里通常不需要DI框架。

    但是。显然,一些更高级别的测试可能仍然需要非模拟依赖项。例如,您希望对一组大数据进行测试,而不希望创建特殊的假数据源,因此将其保存在真实的数据库中(可能还对该数据进行了一些UI测试)。在这种情况下,我仍然会尽量保持简单,在类设置/测试设置方法中初始化测试。

    你看,你在这里要小心。每当您进行大型、复杂的测试时,您都会:

    1. 创建额外的复杂代码,这将需要支持工作。
    2. 创建一个没有明确失败原因的测试。由于那天的连接不好,它可能会失败。你不能依赖它的结果。
    3. 创建一个不能轻松快速运行的测试,例如,在签入时。更少的人会运行它,更多的虫子会通过。

    等。。。