我试图使用System.IO.Abstraction项目和System.IO.Abstraction.TestingHelpers来模拟FileStream。
这是使用我要测试的文件流的代码:
private readonly IFileSystem _fileSystem;
public void ExtractImageAndSaveToDisk(IXLPicture xlPicture, string filePath)
{
using (MemoryStream ms = new MemoryStream())
{
xlPicture.ImageStream.CopyTo(ms);
using (FileStream fs = (FileStream)_fileSystem.FileStream.Create(filePath, FileMode.Create))
{
ms.CopyTo(fs);
fs.Flush();
fs.Close();
}
}
}我就是这样建立测试的:
[TestMethod]
public void CheckFileIsSavedToDisk()
{
// Arrange
var mockFileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
{
{ @"c:\Test\Images\", new MockDirectoryData() },
});
var xlPicture = GetXLPicture();
var filePath = @"c:\Test\Images\myimage.jpeg";
var sut = new CostSheetImageExtractor(mockFileSystem);
// Act
sut.ExtractImagesAndSaveToDisk(xlPicture, filePath);
}运行时我得到了异常:
System.InvalidCastException: Unable to cast object of type 'System.IO.Abstractions.TestingHelpers.MockFileStream' to type 'System.IO.FileStream'.在using (FileStream fs = ...线路上。
第一个想法是,我需要更改FileStream fs以使用真实对象和模拟对象共享的接口,但据我所知,FileStream和MockFileStream没有共享的IFileStream接口,所以我猜我这样做是完全错误的?是否有一种方法可以用System.IO.Abstraction测试这段代码?
这个现有答案似乎认为这是可能的,我也尝试过这样做,但是得到了同样的结果。
发布于 2018-10-22 16:01:22
正如Chris的答案所说,不嘲笑文件系统是最好的选择,但是如果您真的想这样做,那么您的问题几乎包含了答案。
正如您所说的,不存在IFileStream接口,但是如果您查看FileStream,您会发现它继承了抽象类Stream,这是各种流数据源的公共基类。假冒的MockFileStream也应该从那里继承。
因此,尝试更改代码以使用抽象类:
using (Stream fs = (Stream)_fileSystem.FileStream.Create(filePath, FileMode.Create))
{
ms.CopyTo(fs);
fs.Flush();
fs.Close();
}它仍然保留所有的基本方法,您的代码只使用基本方法。
发布于 2018-10-22 15:48:33
我的第一个反应是,您几乎不需要模拟文件系统。您有一个真正的一个,完全工作,在您的机器上,在您的构建服务器上,甚至在您的CI管道容器中,它的工作速度也非常快。那为什么要嘲笑它呢?表面上看,这似乎是一种浪费。嘲弄几乎总是一种代价的妥协,所以不嘲笑通常更好。
如果您使用此路由并针对文件系统进行测试,您可能需要的是类似于System.IO.Directory.GetCurrentDirectory()或System.IO.Path.GetTempPath()的东西,以获得您的测试套件可以调用自己的位置,然后可靠地进行写入、读取和(可选)删除。
https://stackoverflow.com/questions/52933069
复制相似问题