【问题标题】:Mock File IO static class in c#C#中的模拟文件IO静态类
【发布时间】:2011-09-23 21:35:50
【问题描述】:

我是单元测试的新手,我需要在 System.IO 命名空间中模拟 File 静态类。 我正在使用 Rhinomock,最好的方法是什么,

假设我需要模拟 File.Exists,File.Delete ...

【问题讨论】:

  • 本站已有大量示例,请使用搜索按钮
  • 有时人们不知道该搜索什么,也许您可​​以举一些例子而不是完全无用。只是一个想法。

标签: c# unit-testing nunit rhino-mocks


【解决方案1】:

你不能用 Rhino mock 来模拟静态方法。请参阅this question 了解更多信息。您可以创建一个外观类来包装您将使用的文件系统调用,然后创建一个模拟版本。

【讨论】:

  • 与其制作自己的外观,不如使用别人已经为您编写的外观:systemioabstractions.codeplex.com
  • 谢谢,太好了,我打算用这个开源的
  • 不确定我是否会将我的鸡蛋放在一个只有大约 50 人愿意使用的篮子里……但这是你的项目。
  • @CrazyDart - 并不是所有的鸡蛋都放在篮子里。它是开源的,如果您喜欢,请为自己保留一份源代码。
【解决方案2】:

您应该创建一个名为 IFileService 的包装器服务,然后您可以创建一个使用静态数据的混凝土以在您的应用程序中使用,以及一个模拟 IFileService 将具有用于测试的假功能。使它成为你必须将 IFileService 传递给构造函数或任何类使用它的属性,这种方式正常操作需要你传递 IFileService。请记住,在单元测试中,您只是在测试代码的那一部分,而不是像 IFileService 那样调用它的东西。

interface IFileService
{
    bool Exists(string fileName);
    void Delete(string fileName);
}

class FileService : IFileService
{
    public bool Exists(string fileName)
    {
        return File.Exists(fileName);
    }

    public void Delete(string fileName)
    {
        File.Delete(fileName);
    }
}

class MyRealCode
{
    private IFileService _fileService;
    public MyRealCode(IFileService fileService)
    {
        _fileService = fileService;
    }
    void DoStuff()
    {
        _fileService.Exists("myfile.txt");
    }
}

【讨论】:

    【解决方案3】:

    另见VadimSystemWrapper。你可以用它模拟a lot of system classes,但你需要应用dependency injection 模式来使你的代码可测试。

    [Test]
    public void Check_that_FileInfo_methods_Create_and_Delete_are_called()
    {
        // Add mock repository.
        IFileInfoWrap fileInfoRepository = MockRepository.GenerateMock<IFileInfoWrap>();
        IFileStreamWrap fileStreamRepository = MockRepository.GenerateMock<IFileStreamWrap>();
    
        // Create expectations
        fileInfoRepository.Expect(x => x.Create()).Return(fileStreamRepository);
        fileStreamRepository.Expect(x => x.Close());
        fileInfoRepository.Expect(x => x.Delete());
    
        // Test
        new FileInfoSample().CreateAndDeleteFile(fileInfoRepository);
    
        // Verify expectations.
        fileInfoRepository.VerifyAllExpectations();
        fileStreamRepository.VerifyAllExpectations();
    }  
    

    【讨论】:

      【解决方案4】:

      我还使用了包装类。我使用这个工具来轻松生成诸如 System.IO.File 之类的包装类

      https://www.nuget.org/packages/Digitrish.WrapperGenerator/

      安装包后,只需在包管理器控制台上输入以下内容

      Scaffold Wrapper System.IO.File

      这将生成 IFile.cs 接口和一个创建包装类 File.cs。然后您可以使用 IFile 来 Mock 和 File.cs 进行真正的实现。

      【讨论】:

        【解决方案5】:

        为什么不使用 MS Fakes?与 RhinoMocks、SystemWrapper.Wrapper 和 SystemWrapper.Interface 相比,这不是很简单吗?

        【讨论】:

        • 据我了解,MS Fakes 是 VS Enterprise 独有的功能。
        • 请注意,MS Fakes 自 VS 2012 起可用,他在此之前发布了问题!以前有 MS 痣,但不确定它的极限。
        【解决方案6】:

        除了你不能模拟静态容易回答。

        我想指出你不应该嘲笑 File.IO 类型,因为它不是你拥有的类型。你应该only Mock types that you own

        【讨论】:

          【解决方案7】:

          您可以为此使用 moq 框架。它是开源的 google 项目,您可以从这里下载。 Download Moq framework

          要全面了解如何在 C# 中使用 moq,请参阅以下文章。

          http://learningcsharpe.blogspot.com/2011/11/how-to-use-moq-library-for-your-unit.html

          谢谢, 厄兰蒂卡。

          【讨论】:

          猜你喜欢
          • 2010-09-07
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 2013-06-20
          • 1970-01-01
          • 2018-03-29
          相关资源
          最近更新 更多