.NET单元测试mock IFormFile时Data文件夹相对路径不生效如何解决
解决方案
方案1:直接读取嵌入资源(优先推荐)
你已经将测试文件设置为Embedded Resource,完全不需要依赖物理文件路径,直接从程序集的嵌入资源中读取流即可,跨设备完全通用:
- 先确认你的嵌入资源名称,默认规则为
测试项目默认命名空间.文件夹名.文件名,按你的项目结构资源名应为MeterReadings.Core.Tests.Data.Meter_Reading.csv。如果不确定资源名称,可在代码中调用assembly.GetManifestResourceNames()打印所有嵌入资源名确认即可。 - 替换原读取物理文件的代码即可。
方案2:使用物理文件的正确相对路径写法
如果你要读取物理文件,不要用Environment.CurrentDirectory,单元测试运行时该路径不一定指向测试项目目录,要先获取当前测试程序集的运行目录再拼接路径:
// 获取测试程序集所在目录 var assemblyLocation = Assembly.GetExecutingAssembly().Location; var assemblyDirectory = Path.GetDirectoryName(assemblyLocation); // 拼接文件路径,要先把CSV文件的"复制到输出目录"属性设为"如果较新则复制",测试时Data文件夹会同步到输出目录 var filePath = Path.Combine(assemblyDirectory, "Data", "Meter_Reading.csv"); var PhysicalFile = new FileInfo(filePath);
修正后的完整测试代码(采用嵌入资源方案)
[Fact] public void HasCorrectImageType() { var formFile = new Mock<IFormFile>(); var fileName = "Meter_Reading.csv"; // 读取嵌入资源流 var assembly = Assembly.GetExecutingAssembly(); var resourceName = "MeterReadings.Core.Tests.Data.Meter_Reading.csv"; using var resourceStream = assembly.GetManifestResourceStream(resourceName); if (resourceStream == null) { throw new FileNotFoundException("未找到嵌入的测试资源", resourceName); } // 把资源流拷贝到MemoryStream var memory = new MemoryStream(); resourceStream.CopyTo(memory); memory.Position = 0; formFile.Setup(_ => _.FileName).Returns(fileName); formFile.Setup(_ => _.Length).Returns(memory.Length); formFile.Setup(_ => _.OpenReadStream()).Returns(memory); var controller = new ScanController(); var file = formFile.Object; var result = controller.Scan(file); Assert.IsAssignableFrom<OkObjectResult>(result); }
额外说明:你原来代码中的writer.Write(PhysicalFile.OpenRead())是错误写法,直接传入Stream对象不会写入文件内容,只会写入Stream类的ToString()结果,用流拷贝方法CopyTo即可正确写入内容。另外原代码中提前调用formFile.Verify()没有意义,可根据需要放在断言后验证mock对象的调用情况。
内容的提问来源于stack exchange,提问作者user16405900
相关产品推荐
相关产品推荐

