C# 中的模拟文件 IO 静态类

发布于 2024-11-17 08:07:00 字数 124 浏览 3 评论 0原文

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

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

I am new to Unit Testing, and I need to mock the File static class in System.IO namespace.
I am using Rhinomock, what is the best way to accomplish this,

Lets say I need to mock the File.Exists,File.Delete ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

蓝天白云 2024-11-24 08:07:00

您无法使用 Rhino 模拟来模拟静态方法。有关详细信息,请参阅此问题。您可以创建一个外观类来包装您将使用的文件系统调用,然后创建它的模拟版本。

You can't mock static methods with Rhino mock. See this question for more info. You could create a facade class to wrap the file system calls you will use and then create a mock version of that.

满地尘埃落定 2024-11-24 08:07:00

您应该创建一个名为 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");
    }
}

You should create a wrapper service called IFileService, then you can create a concrete that uses the statics for use in your app, and a mock IFileService that will have fake functionality for testing. Make it so you have to pass IFileService into the constructor or a property for what ever class is using it, this way normal operation requires you pass in the IFileService. Remember in Unit Testing you are testing just that part of code not the things its calling to like 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");
    }
}
欢你一世 2024-11-24 08:07:00

另请参阅 VadimSystemWrapper。你可以用它模拟很多系统类,但是你需要应用依赖注入模式以使您的代码可测试。

[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();
}  

See also Vadim's SystemWrapper. You can mock a lot of system classes with it, but you will need to apply the dependency injection pattern to make your code testable.

[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();
}  
一笑百媚生 2024-11-24 08:07:00

我还使用了包装类。我使用此工具轻松生成包装类,例如 System.IO.File

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

安装软件包后,只需在软件包管理器控制台上键入以下内容即可

Scaffold Wrapper System.IO.File

这将生成 IFile.cs接口和一个具体的包装类 File.cs。然后你可以使用IFile to Mock和File.cs进行真正的实现。

I also used wrapper classes. I use this tool to easily generate wrapper classes such as System.IO.File

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

Once you installed the package just type the following on Package Manager Console

Scaffold Wrapper System.IO.File

This will generate IFile.cs interface and one concreate wrapper class File.cs. Then you can use the IFile to Mock and File.cs for the real implementation.

三岁铭 2024-11-24 08:07:00

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

Why not using MS Fakes? Wouldn't that be simple, already supported compared to RhinoMocks, SystemWrapper.Wrapper and SystemWrapper.Interface?

莫言歌 2024-11-24 08:07:00

除了你不能轻易嘲笑静态之外。

我想指出的是,您不应该嘲笑 File.IO 类型,因为它不是您拥有的类型。您应该仅您拥有的模拟类型

In addition to the you can't mock Static easily answer.

I'd like to point out that you shouldn't be mocking File.IO type, because it is not a type that you own. You should only Mock types that you own.

猫性小仙女 2024-11-24 08:07:00

您可以为此使用起订量框架。它是开源谷歌项目,您可以从这里下载。
下载 Moq 框架

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

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

谢谢,
埃兰迪卡。

You can use moq framework for this.It is open source google project which you can download from here.
Download Moq framework

To get fully understanding about how to use moq with C# please refer the following article.

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

thanks,
Erandika.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文