将依赖项注入测试

时间:2010-02-11 12:44:05

标签: unit-testing design-patterns dependency-injection

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

但是,有时测试本身具有依赖关系,或者需要将依赖关系注入到它本身无法创建的SUT中。例如,在测试与数据库交互的类时,测试需要知道连接字符串和目录名称等,这些不能被硬编码,因为对于运行测试的每个人来说它们不一定相同。

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

3 个答案:

答案 0 :(得分:3)

完全自动化测试的原则是:您应该能够从源代码控制存储库中下载所有源代码,然后运行测试。

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

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

  1. 创建有问题的数据库
  2. 运行测试
  3. 在最后一个测试用例后再次删除数据库
  4. 如果由于某种原因你无法做到这一点,你唯一能做的就是在你的源控制系统中有一个配置文件,其中包含测试环境中所有机器的机器特定条目;例如对于机器 Tst1 ,连接字符串是一个值,但对于 Tst2 ,它是另一个值。

    这可能会很快变得难看,因此让测试负责Fixture Setup和Teardown要容易得多,因为这意味着他们可以简单地使用硬编码值或现场生成的值。

    这与DI无关......

答案 1 :(得分:1)

DI与依赖性复杂性斗争,而您的单元测试必须在大多数情况下非常简单。典型的单元测试将检查一个孤立类的一个孤立方面。而不是它的所有依赖项,你创建模拟和(通常)通过CUT(Class Under Test)构造函数注入它们。您通常不需要DI框架。

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

你知道,你需要在这里小心。每当你做一个大而复杂的测试时,你:

  1. 创建其他需要支持的复杂代码。
  2. 创建一个没有明确失败原因的测试。由于当天连接不良,它可能会失败。你不能依赖它的结果。
  3. 创建一个无法轻松快速运行的测试,例如,在办理登机手续时。人们不会经营它,会有更多的错误。
  4. 等...

答案 2 :(得分:1)

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

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

由于它们是集成测试,因此它们与单元测试的种类不同。 “独立”并不再重要了。

获得不同用户的集成测试设置的最佳方法是使它们与最终应用程序获得它们的方式相同。如果您使用的是Java,则可能有一个属性文件。在Python中,我们有专门的Django设置文件进行集成测试。