【问题标题】:Verify that method argument exists on disk验证磁盘上是否存在方法参数
【发布时间】:2014-03-25 11:48:52
【问题描述】:

我有一个要测试的对象。它应该调用一个名为ProcessFile() 的方法,该方法将文件名作为输入。这个方法是模拟的。

我可以很容易地验证该方法被调用了预期的次数。实际文件名是随机生成的,然而如果您调用ProcessFile(),那么显然它应该处理的文件必须存在于磁盘上。如果没有,则说明有问题。

目前被测代码已损坏;它有时会使用不存在的文件名调用该方法。我真的,真的,真的很想让错误信息说哪个文件不存在。

我能够通过某种方式进行测试以检测出某些问题,如下所示:

mockProcessor.Verify(
  x => x.ProcessFile(It.Is<string>(s => s != null && File.Exists(s)),
  Times.Exactly(103)
);

现在,如果磁盘上不存在任何文件,则测试将失败。但是,它未能声称该方法没有被调用所需的次数。我理解为什么这样说,但这是一个高度误导性的信息。 真正的 问题是磁盘上不存在文件 - 测试输出并没有特别清楚地说明这一事实。 我知道发生了什么,但下一个可怜的 #### 处理此代码可能没有线索。

我真正想要的是检查是否发生了所需的调用次数,以及在每次这样的调用中,磁盘上是否存在指定的文件。有什么建议吗?

【问题讨论】:

  • 你真的不应该使用磁盘上的文件,你应该在代码中使用假文件。
  • @SamLeach 不可能。这不是单元测试,而是集成测试。
  • 我明白了。我已经添加了集成测试标签。
  • 如果是集成测试,为什么要使用 Moq 来测试文件是否存在而不是 ProcessFile() 的生产代码?
  • @StuperUser 我们在其他地方对ProcessFile() 进行了测试。 此 测试用于检查该方法是否被正确调用 - 在本例中不是。

标签: c# integration-testing moq


【解决方案1】:

您可以将s =&gt; s != null &amp;&amp; File.Exists(s) 更改为语句体:

s => 
{
    if (s == null)
    {
        return false;
    }

    if (!File.Exist(s))
    {
        throw new FileNotFoundException(s);
    }

    return true;
}

或者提取一个方法并调用它 (s =&gt; FileNotNullAndExists(s))。

【讨论】:

    【解决方案2】:

    我想出了一个使用回调的解决方案:

    Action<string> callback = (file) => Assert.IsTrue(File.Exists(file));
    
    mockProcessor.Setup(x => x.ProcessFile(It.IsAny<string>)).Callback(callback);
    

    事实证明,我试图寻找的错误取决于ProcessFile() 删除处理后的文件这一事实。当然,将它添加到上述回调中是微不足道的。

    所以现在我可以开始实际尝试修复错误了...

    【讨论】:

      猜你喜欢
      • 2018-10-28
      • 2012-05-13
      • 2012-08-23
      • 2019-12-27
      • 2011-01-05
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 2013-01-24
      相关资源
      最近更新 更多