如何设置文件系统模拟以返回 DriveInfo 信息

问题描述 投票:0回答:1

我正在学习在单元测试中模拟文件系统,并且有一个我想使用模拟进行测试的简单方法:

    public class FileStatsUtility
    {
        private IFileSystem _fileSystem;

        public FileStatsUtility(IFileSystem fileSystem)
        {
            _fileSystem = fileSystem;
        }

        public FileStatsUtility() : this(fileSystem: new FileSystem()) //use default implementation which calls System.IO
        {
        }

        public long GetFreeSpaceMb(string folder)
        {
            // returns the free space in Mb of the filesystem this folder is on
            string? driveName = Path.GetPathRoot(folder);
            if (!string.IsNullOrEmpty(driveName)) 
            {
                var drive = _fileSystem.DriveInfo.New(driveName);
                return drive.AvailableFreeSpace / (1024 * 1024);
            }
            else return -1;
        }
   }

我尝试在单元测试中注入模拟文件系统

[TestMethod]
        public void ShouldReturnCorrectFreeSpaceMb ()
        {
            var testDir = "C:\anystring";
            var fsProviderMock = new Mock<IFileSystem>();
            var fsu = new FileStatsUtility(fsProviderMock.Object);

            //arrange
            fsProviderMock
                .Setup(m => m.DriveInfo.New(testDir))
                .Returns(new DriveInfo("C:\")
                {
                    DriveType = DriveType.Fixed,
                    AvailableFreeSpace = 500 * 1024 * 1024
                });

            //act
            var reportedFreeSpace = fsu.GetFreeSpaceMb(testDir);

            //assert
        }

这不会编译。 DriveType 和AvailableFreeSpace 是只读的。我想我错过了一些简单的东西,但无法理解它。

如何设置模拟以返回填充的 DriveInfo?

c# unit-testing mocking
1个回答
0
投票

对于像文件系统这样复杂的东西,我建议为您的模拟创建一个常规类,而不是使用模拟框架。如果您需要模拟界面的一小部分,模拟框架会很方便。但对于像文件系统这样复杂的东西来说,可能比创建自己的类来模拟内存中的文件系统更好。这也将更容易重用于其他类型的测试。

我还会考虑您打算如何使用文件系统。如果您只想存储和检索数据,您可能会考虑一些更抽象的东西,例如

IFileRepository
,它不关心可用空间或权限等文件系统详细信息。这应该可以更轻松地进行多种实现,并使界面更有用。

如果您只是在 Windows 文件系统周围创建一个薄包装器,那么由于难以复制的所有各种特殊行为,您无法切实地进行任何其他有效的实现。包括测试的模拟实现。例如,考虑一下,

  • 区分大小写
  • 非法文件名和字符
  • 最大文件名长度
  • 符号链接
  • 等等...
© www.soinside.com 2019 - 2024. All rights reserved.