我有一个可以返回图像数据 URL 的服务,我想对其进行单元测试。
以下是其部分内容:(“path”参数是真实的路径路由)
...
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 ......
}
所以我的问题是,如何在没有真实路径的情况下模拟 FileStream?我使用了xUnit和Substitute,发现FileStream可以使用Substitute,但不知道为什么它需要参数的真实路径。我还能怎样尝试?除了使用wrapper还有什么办法吗?
感谢您的任何建议。
解决方案是通过接受
Stream
对象来概括方法参数。我假设你当前的方法签名是这样的
public byte[] GetImageData(string path)
将方法更改为:
public byte[] GetImageData(Stream stream)
{
byte[] buffer = new byte[stream.Length];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
// return your data.
}
通过这种方式,您将获取
FileStream
的责任转移给了客户,并传递了 FileStream
。现在你在传递参数时处于更自由的情况:在实际代码中你可以传递一个真正的FileStream
:
var fileStream = new FileStream("path/to/file", FileMode.Open, FileAccess.Read);
byte[] data = parser.GetImageData(fileStream);
或者您可以根据您的测试代码中的需要自由创建
MemoryStream
:
Stream stream = new MemoryStream();
// Manipulate your stream object as you like.
byte[] data = parser.GetImageData(stream);
这实际上是接口编程,而不是具体实现和依赖注入的示例。这种方法的一个好处是,您不会在单元测试中遭受磁盘 IO 的性能损失。