将FileInfo作为参数的单元测试方法

时间:2016-02-09 17:03:16

标签: c# unit-testing encoding io

我有一个方法,它以FileInfo对象作为参数,并检查相应的文件是否以UTF-8编码。

我使用MSTest编写了一些单元测试,使用添加到UnitTest项目的真实文本文件,这些文件使用DeploymentItem属性进行部署。然后,我创建指向已部署文件的FileInfo个对象,并使用它们测试方法。像这样:

    [TestMethod]
    [DeploymentItem(@"..\..\Import\UTF8.txt")]
    public void TestUTF8Detection()
    {
        FileInfo fileInfo = new FileInfo("UTF8.txt");
        bool isUTF8= FormatVerification.IsUTF8(fileInfo);
        Assert.IsTrue(isUTF8);
    }

但是,我已经读过,使用真实文件可能会更慢,更不值得信任(例如herehere),所以我想我会怎样做嘲笑文件。我想我必须:

  • 创建一个实际测试的子方法,而不是原始方法 一个可以称之为的,并且将其作为参数a FileStream代替FileInfo
  • 在UTF-8中创建FileStream编码(或不编码),并将其传递给子方法。

所以,我有一些问题,从更具体到更一般:

  1. 如何在没有真实文件的情况下创建以UTF-8编码的FileStream对象?
  2. 这个子方法的创建是否是允许模拟文件的唯一选择?
  3. 原始方法怎么样?我可以用某种方式测试吗?
  4. 创建这种子方法(仅允许单元测试)被认为是一种好的做法吗?
  5. 我是否真的应该避免在单元测试中使用真实文件,或者是否存在类似这样的情况?

2 个答案:

答案 0 :(得分:1)

FileInfo已被密封,因此您无法进行继承和覆盖技巧。

我会使用像SystemWrapper这样的东西,或者像为Haukinger建议的那样滚动我自己的FileInfo接口,然后一旦你的代码依赖于界面,你应该很容易模仿你需要的行为。

答案 1 :(得分:0)

我猜你最好的选择是将FileInfo抽象为IMyFileInfo和一个从文件名创建的工厂(也就是说,它会创建原始的FileInfo加上一个包装器)

然后,测试可以创建模拟IMyFileInfo)。您的界面/包装器应该公开FileInfo中所需的IsUTF8内的所有内容。

然后,生产代码应该使用工厂而不是new来创建包装而不是真正的FileInfo