如何使用Visual Studio内置的自动化测试单元测试文件写入方法?

5
  1. 我使用Visual Studio 2008 Professional自动化测试。我有一个写入文件的函数。我想对文件写入函数进行单元测试。我在某个地方读到过,我必须以某种方式模拟文件。我不知道如何做。你能帮忙吗?

  2. 如何对从互联网下载页面的方法进行单元测试?

4个回答

7
如果该方法必须自己打开文件流,那么很难进行模拟。但是,如果您可以将流传递到该方法中,并使其写入该流,则可以传递一个MemoryStream。另一种重载可以使用较少的参数打开文件并将FileStream传递给其他方法。
这样,您就不会获得完整的覆盖范围(除非您编写了一两个真正命中磁盘的测试),但是大部分逻辑都在接受流参数的方法中进行了完全测试。

所以我可以将方法分为两个部分,一个打开文件流并调用第二个部分并传递文件流,这样我就能够对第二个部分进行单元测试。完整的覆盖测试会从磁盘读取吗? - Jader Dias
没错。对于那些最容易在自己的文件中阅读的测试数据,可以使用Assembly.GetManifestResourceStream。 - Jon Skeet

6
取决于你的代码与底层的接口有多接近;例如,你可以使用 Stream 并将 MemoryStream 传递给代码(并检查内容)。你也可以直接写入文件系统(在临时区域),检查内容后删除。如果你的代码高于文件系统,你可以编写一个可模拟的 IFileSystem 接口,其中包含你需要的高级方法(如 WriteAllBytes / WriteAllText)。但是模拟流API可能会很麻烦。
对于从互联网下载(或模拟)... 你可以(例如)编写一个 IWebClient 接口,其中包含你需要的函数(如 DownloadString 等);模拟它以返回固定内容,并使用像 WebClient 这样的东西作为实际实现的基础。当然,你需要针对真实站点测试实际实现。

2
将实际实现与真实网站进行测试的过程称为“集成测试”,大多数单元测试框架都允许您从标准测试中组织出这些测试。由于实际测试的是“物理”事物而不仅仅是虚假的东西,因此您运行这些集成测试的次数会比标准单元测试少,因为它们会很慢。 - Sekhat

4

如果您的测试目标是测试文件是否已经创建,那么它是一个集成测试,而不是单元测试。

如果您的目标是测试是否将正确的事物写入文件中,请将文件访问隐藏在接口后面,并提供内存实现。

对于网页访问也是如此。

interface IFileService
{
     Stream CreateFile(string filename); 
}

class InMemoryFileService : IFileService
{
    private Dictionary<string, MemoryStream> files = new Dictionary<string, MemoryStream>();

    public Stream CreateFile(string filename)
    {
       MemoryStream stream = new MemoryStream();
       files.Add(filename, stream);
       return stream;
    }

    public MemoryStream GetFile(string filename)
    {
         return files[filename];
    }
} 

使用 GetFile,您可以找到应该写入磁盘的内容。

1

你实际上不想在函数中直接调用写文件的操作,而是要将文件I/O封装在一个带有接口的类中。

然后,你可以使用类似Rhino Mocks的工具来创建实现该接口的模拟类。


问题在于,大多数非平凡的基于文件的工作涉及多次(循环)调用流文件API(读取器/写入器或流) - 非常难以模拟,而不需要在模拟中编写比您正在测试的代码更多的代码。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接