【问题标题】:How can the FileInfo class be mocked using System.IO.Abstractions?如何使用 System.IO.Abstractions 模拟 FileInfo 类?
【发布时间】:2022-09-27 22:00:37
【问题描述】:

我已经将System.IO.Abstractions.IFileSystem 接口注入到一个类中,这样我就可以对文件系统交互进行单元测试。班上有一个地方使用new FileInfo(fileName)。使用IFileSystem 接口和MockFileSystem 时的替代品是什么?

_fileSystem.File.OpenRead 替换File.OpenRead 很简单......

public string? Decrypt(string encryptedFilePath, string privateKeyArmor, string passPhrase)
    {
        try
        {
            using var privateKeyStream = new MemoryStream(Encoding.ASCII.GetBytes(privateKeyArmor));
            using var encryptedFileStream = _fileSystem.File.OpenRead(encryptedFilePath);

            var inputStream = PgpUtilities.GetDecoderStream(encryptedFileStream);
...

...但我不知道如何在这里替换new FileInfo(fileName)

private byte[] CompressFile(string fileName, CompressionAlgorithmTag algorithm)
    {
        var outputStream = new MemoryStream();
        var compressedDataGen = new PgpCompressedDataGenerator(algorithm);
        PgpUtilities.WriteFileToLiteralData(compressedDataGen.Open(outputStream), PgpLiteralData.Binary,
            new FileInfo(fileName));
...

我试过_fileSystem.FileInfo.FromFileName(fileName),但它返回IFileInfo 而不是FileInfoWriteFileToLiteralData 方法不会接受。

  • 您不能模拟构造函数。

标签: c# unit-testing mocking


【解决方案1】:

有一个辅助函数 FileInfo.FromFileName(string fileName) 可用于创建/使用模拟 IFileInfo 对象

public class FileInfoTest
{
    private readonly IFileSystem _fileSystem;

    public FileInfoTest()
        : this (new FileSystem())

    {
    }

    internal FileInfoTest(IFileSystem fileSystem)
    {
        _fileSystem = fileSystem;
    }

    public bool GetIsReadOnly(string path)
    {
        var info = _fileSystem.FileInfo.FromFileName(path);
        return info.IsReadOnly;
    }

}

为了证明这一点,我有一个非只读的物理文件。

第一个测试,返回物理文件的 IsReadonly 状态。
第二个,返回一个模拟的 IFileInfo 对象,其中 IsReadOnly 设置为 true。

[TestMethod]
public void CheckFileInfoAgainstPhysicalFile()
{
    var tester = new FileInfoTest();
    var isReadOnly = tester.GetIsReadOnly(@"c:\dev\File.txt");
    Assert.IsFalse(isReadOnly);
}

[TestMethod]
public void CheckFileInfoAgainstMock()
{
    var mockFileInfo = new Mock<IFileInfo>();
    mockFileInfo.SetupGet(mk => mk.IsReadOnly).Returns(true);   
    var mockFileSystem = new Mock<IFileSystem>();
    mockFileSystem.Setup(mk => mk.FileInfo.FromFileName(@"c:\dev\File.txt")).Returns(mockFileInfo.Object);
        
    var tester = new FileInfoTest(mockFileSystem.Object);
    var isReadOnly = tester.GetIsReadOnly(@"c:\dev\File.txt");
    Assert.IsTrue(isReadOnly);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多