I had a service that would return an image's data URLs, and I want to do unit test for it.
The following is part of its: ("path" parameter is a real path route)
...
using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[fileStream.Length];
int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
if (bytesRead < buffer.Length)
{
return ...
}
...
return ......
}
So my question is, how can I mock FileStream without a real path? I used xUnit and Substitute and found that FileStream can use Substitute but not know why it needs a real path for the parameter. How else can I try? Is there any way except to use wrapper?
Thanks for any advice.
The solution is generalizing the method parameter by accepting a
Streamobject. I assume your current method signature is something likeChange your method to:
In this way, you shift the responsibility of getting the
FileStreamto the clients and pass in aFileStreaminstead. Now you are in a more liberal situation when passing the parameter: In actual code you can pass in a realFileStream:or you can freely create a
MemoryStreamaccording to your needs in your test code:This is actually an example of programming to interfaces, not concrete implementations and dependency injection. One bonus with this approach is that you will not incur the performance penalty of disk IO in your unit tests.