Visual studio 如何使用Visual Studio对文件写入方法进行单元测试';s内置自动测试?

Visual studio 如何使用Visual Studio对文件写入方法进行单元测试';s内置自动测试?,visual-studio,visual-studio-2008,unit-testing,mocking,automated-tests,Visual Studio,Visual Studio 2008,Unit Testing,Mocking,Automated Tests,我使用VisualStudio2008专业自动测试。我有一个写文件的函数。我想对文件写入函数进行单元测试。我在某个地方读到过,我不得不以某种方式模拟一个文件。我不知道怎么做。你能帮忙吗 如何对从Internet下载页面的方法进行单元测试 如果该方法必须打开文件流本身,那么很难模拟。但是,如果您可以将一个流传递到该方法中,并使其写入该方法,那么您可以改为传递一个MemoryStream。另一种重载方法可以使用更少的参数,打开文件并将FileStream传递给另一个方法 这样你就不会得到完全的覆盖(

我使用VisualStudio2008专业自动测试。我有一个写文件的函数。我想对文件写入函数进行单元测试。我在某个地方读到过,我不得不以某种方式模拟一个文件。我不知道怎么做。你能帮忙吗

  • 如何对从Internet下载页面的方法进行单元测试


  • 如果该方法必须打开文件流本身,那么很难模拟。但是,如果您可以将一个流传递到该方法中,并使其写入该方法,那么您可以改为传递一个MemoryStream。另一种重载方法可以使用更少的参数,打开文件并将FileStream传递给另一个方法


    这样你就不会得到完全的覆盖(除非你写了一两个测试,它确实击中了磁盘),但是你的大部分逻辑都是在经过充分测试的代码中,在采用流参数的方法中。

    这取决于你的代码与具体细节的接近程度;例如,您可以改为在
    s中工作,并将
    内存流
    传递给代码(并检查内容)。您可以只写文件系统(在临时区域),检查内容,然后丢弃它。当然,如果您的代码略高于文件系统,您可以使用所需的高级方法(如
    writealBytes
    /
    writealText
    )编写一个可模拟的
    IFileSystem
    接口。不过,模仿流式API将是一件痛苦的事情


    从互联网下载(或假装)。。。您可以(例如)编写一个带有所需函数的
    IWebClient
    接口(如
    DownloadString
    等);模拟它以返回固定内容,并使用类似于
    WebClient
    的内容作为实际实现的基础。当然,您需要针对实际站点测试实际实现。

    您实际上不希望调用直接在函数中写入文件,而是将文件I/O封装在带有接口的类中


    然后,您可以使用类似Rhino mock的东西来创建实现接口的模拟类。

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

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

    网页访问也是如此

    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];
        }
    } 
    
    接口IFileService
    {
    流创建文件(字符串文件名);
    }
    MemoryFileService中的类:IFileService
    {
    私有字典文件=新字典();
    公共流CreateFile(字符串文件名)
    {
    MemoryStream stream=新的MemoryStream();
    添加(文件名、流);
    回流;
    }
    公共内存流GetFile(字符串文件名)
    {
    返回文件[文件名];
    }
    } 
    

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

    因此我可以将该方法拆分为2,一个打开文件流并调用第二个通过文件流的方法,这样我就可以对第二个进行单元测试。一个完整的覆盖率测试将从磁盘读取数据?完全正确。对于最容易在自己的文件中读取的测试数据,请使用Assembly.GetManifestResourceStream。问题是,大多数基于文件的非琐碎工作都涉及对流文件API(读写器或流)的多个(循环)调用-如果不在模拟中编写比您正在测试的代码更多的代码,那么很难进行模拟。针对真实站点测试实际实现将是“集成测试”,大多数单元测试框架允许您从标准测试中组织测试。与标准单元测试相比,您运行这些集成测试的次数要少一些,因为它们会比较慢(因为实际上是针对“物理”的东西而不是伪造的东西进行测试)。