简体   繁体   English

如何使用 System.IO.Abstractions 模拟 FileInfo class?

[英]How can the FileInfo class be mocked using System.IO.Abstractions?

I have injected the System.IO.Abstractions.IFileSystem interface into a class so that I can unit test file system interactions.我已将System.IO.Abstractions.IFileSystem接口注入到 class 中,以便对文件系统交互进行单元测试。 There is one place in the class that uses new FileInfo(fileName) . class 中有一处使用new FileInfo(fileName) What is the replacement for that when using the IFileSystem interface and MockFileSystem ?使用IFileSystem接口和MockFileSystem时的替代品是什么?

Replacing File.OpenRead with _fileSystem.File.OpenRead is simple..._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);
...

...but I don't know how to replace new FileInfo(fileName) here. ...但我不知道如何在这里替换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));
...

I tried _fileSystem.FileInfo.FromFileName(fileName) , but that returns IFileInfo instead of FileInfo and the WriteFileToLiteralData method won't take that.我尝试_fileSystem.FileInfo.FromFileName(fileName) ,但它返回IFileInfo而不是FileInfo并且WriteFileToLiteralData方法不会这样做。

There is a helper function FileInfo.FromFileName(string fileName) which can be used to create/use a mock IFileInfo object有一个助手 function FileInfo.FromFileName(string fileName)可用于创建/使用模拟IFileInfo object

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;
    }

}

To demonstrate this I have a physical file which is not read-only.为了证明这一点,我有一个非只读的物理文件。

The first test, returns the IsReadonly state of the physical file.第一个测试,返回物理文件的 IsReadonly state。
The second, returns a mocked IFileInfo object with IsReadOnly set to true.第二个,返回一个模拟的 IFileInfo object 并将 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);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM