【问题标题】:Should I unit test code with no obvious returns from methods?我应该对没有明显方法返回的代码进行单元测试吗?
【发布时间】:2012-12-20 08:59:38
【问题描述】:

我有一个类,其唯一目的是通过接口在其他类上运行方法。

测试类的接口没有问题,但是运行器实际上并没有做任何事情,并且(就目前而言)传递给构造函数的唯一参数是私有的。

在我的例子中,这些类将文本文件导入数据库。

internal DataImporter
{
  private List<IFileImporter> _importers;

  public DataImporter(List<IFileImporter> importers){
    _importers = importers;

  public bool RunImporters()
  {
    //foreach importer, call its "Run" method - each one then does whatever it needs to do
    //however, this need not call a specific "Run" method on IFileImporter
    //I have another app that uses IFileImporter to check for presence of a file first
    //then allow user to choose to import or not.
  }

在我看来这里没有什么可以测试的?我无法测试_importers 的值,也不想仅仅为了测试而将其公开。 DataImporter 是特定于这个实例的,所以创建一个接口似乎没有任何好处。

我在其他地方重用了 IFileImporters,但这是唯一的“批量”导入器,其他的是从 winforms 应用程序手动调用的,还有一些根本不在这个项目中。

那么,我需要对此进行测试吗...我可以对此进行什么测试?

【问题讨论】:

  • 如果这样的 void 方法改变了对象的状态,或者进行了任何外部调用,您可能仍然希望通过测试最终结果而不是具体的返回值来测试它。
  • @ryadavilli - 我同意。现在我正在创建一个从数据库中删除对象的单元测试。该方法返回void,但我仍然可以检查它是否存在于数据库中。
  • 对象实际上是“Main”方法,但使用强类型 List<...> 而不是参数。当前大约 30 个具体的 Importers 中的每一个实际上都在做一些事情……但是这个类只是运行它们的一种方式。我实际上可以将其设为静态并将 List 传递给 Run 方法(也许我应该!)
  • 那么,添加一个“已知”的测试导入器,将它添加到我的类中,检查它是否需要“一个文件”并将其导入到“一个目的地”?
  • 查看 Moq 或等效的模拟框架。它可以设置一个 IFileImporter 的 Mock,您可以使用它来指定所需的行为(返回 True 或 False、抛出异常等)以及断言它是否被调用。

标签: c# unit-testing nunit moq


【解决方案1】:

简而言之,是的。我能想到很多测试。

您的测试通过模拟您在构造函数中传递的 IFileImporters 来确保调用所有导入器。至少,它断言您在构造函数中传递的内容实际上已被该方法使用。

一个测试,以确保如果任何导入程序引发异常,您的类的行为符合您的预期。

如果列表为空,测试应该断言该行为。 (默认为 True 返回?)

如果一个或多个导入器失败,测试还应该断言您所期望的行为。 (对于 RunImporters 结果,您是对导入器结果进行与或或运算吗?)

无论前一个是否失败,该方法是否运行每个导入器,或者在第一次失败时返回 false?

还应该对您的构造函数或断言进行测试,以确定它是否提供了一个空列表。

【讨论】:

    【解决方案2】:

    您可以断言方法已被调用。您可以参考这些问题来了解它是如何完成的:

    您还可以断言在DataImporterclass 中没有遇到异常。

    如果您对所使用的界面有绝对控制权,每个界面返回一个boolean 指示特定操作是否成功可能会有所帮助。

    【讨论】:

      【解决方案3】:

      您的方法返回bool,这就是您开始的地方,例如:

      • 没有进口商时会发生什么?示例:Run_ReturnsFalse_WhenThereIsNoImporters
      • 当其中一个打破(或抛出)时会发生什么?示例:Run_ReturnsFalse_WhenAtLeastOneImporterFails
      • 什么表示成功(我想返回true)?示例:Run_ReturnsTrue_WhenAllImportersSucceed

      你设置你的模拟来模拟每个场景并再次测试。当确实没有可观察到的效果(如返回值)时,您将通过验证是否对模拟对象进行了调用来做到这一点。

      【讨论】:

        猜你喜欢
        • 2014-03-25
        • 1970-01-01
        • 2015-02-26
        • 1970-01-01
        • 2011-01-01
        • 2020-05-30
        • 1970-01-01
        • 2019-11-17
        • 2010-09-29
        相关资源
        最近更新 更多