如何使用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
相关产品推荐
相关产品推荐

