I'm trying to use the System.IO.Abstraction project along with System.IO.Abstraction.TestingHelpers to mock a FileStream
.
This is the code that's using the file stream that I want to test:
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();
}
}
}
And this is how I've set up the testing:
[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);
}
Running that I get the exception:
System.InvalidCastException: Unable to cast object of type 'System.IO.Abstractions.TestingHelpers.MockFileStream' to type 'System.IO.FileStream'.
on the using (FileStream fs = ...
line.
The first thought was that I need to change the FileStream fs
to use an interface that both the real and mock objects share, but as far as I can see there's no IFileStream
interface that FileStream
and MockFileStream
share, so I'm guessing I'm doing this completely wrong?
Is there actually a way to test this code with System.IO.Abstraction?
This existing answer seems to suggest this should be possible, I tried doing it that way too but got the same results.
Not mocking the filesystem is by far the best option, as Chris F Carroll answer says, but if you want to really do that, your question almost contains the answer.
As you said, there is no such thing as an IFileStream
interface, but if you look at the definition of FileStream
you'll find that it inherits the abstract class Stream
, and that's a common base class for all kinds of streamed data sources. The fake MockFileStream
should also inherit from there.
So, try changing your code to use the abstract class instead:
using (Stream fs = (Stream)_fileSystem.FileStream.Create(filePath, FileMode.Create))
{
ms.CopyTo(fs);
fs.Flush();
fs.Close();
}
It still retain all the base methods and your code just uses the base ones.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With