You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用System.IO.Abstractions模拟替换FileInfo实例化调用

替换new FileInfo()适配IFileSystem/MockFileSystem的实现方案

你遇到的类型不匹配问题,根源是BouncyCastle的PgpUtilities.WriteFileToLiteralData方法提供的FileInfo参数重载强依赖System.IO原生的FileInfo密封类,和System.IO.Abstractions提供的IFileInfo抽象没有类型继承关系,无法直接传参。

推荐实现:使用流参数重载,完全适配文件系统抽象

WriteFileToLiteralData本身提供了不依赖FileInfo的重载,支持直接传入文件流、文件名、修改时间等元数据,完全可以通过IFileSystem获取所有需要的参数,不需要直接实例化原生FileInfo,单元测试时MockFileSystem可以正常模拟所有文件相关行为。

替换后的代码实现如下:

private byte[] CompressFile(string fileName, CompressionAlgorithmTag algorithm)
{
    var outputStream = new MemoryStream();
    var compressedDataGen = new PgpCompressedDataGenerator(algorithm);
    
    // 所有文件系统交互全部走IFileSystem抽象
    IFileInfo targetFile = _fileSystem.FileInfo.FromFileName(fileName);
    using var sourceFileStream = targetFile.OpenRead();
    using var compressedTargetStream = compressedDataGen.Open(outputStream);

    // 调用流参数重载,无需传入原生FileInfo实例
    PgpUtilities.WriteFileToLiteralData(
        compressedTargetStream,
        PgpLiteralData.Binary,
        targetFile.Name,
        sourceFileStream,
        targetFile.LastWriteTimeUtc
    );

    // 其余原有业务逻辑保持不变
    // ...
}

方案优势

  • 所有文件操作完全走IFileSystem抽象,和你之前替换File.OpenRead的逻辑保持一致
  • 单元测试使用MockFileSystem时,可以正常模拟文件内容、修改时间、文件不存在等各类场景,不需要访问真实磁盘
  • 没有额外的包装层代码,性能和直接调用原生API基本一致

不推荐的做法

不要尝试将IFileInfo强制转换为FileInfo:MockFileSystem返回的IFileInfo实现是MockFileInfo类型,和原生FileInfo没有继承关系,运行时会抛出类型转换异常。
也不要在该位置直接保留new FileInfo(fileName)写法:这部分代码会直接访问真实文件系统,单元测试时无法被Mock,会导致测试依赖磁盘环境,违背你注入IFileSystem做可测试性改造的初衷。


内容的提问来源于stack exchange,提问作者Matthew MacFarland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:12:23