我有课
ImportProvider
,我想为导入方法编写单元测试。
但这应该是单元测试,所以我不想从文件读取到流。 有什么想法吗?
public class ImportProvider : IImportProvider
{
public bool Import(Stream stream)
{
//Do import
return isImported;
}
}
public interface IImportProvider
{
bool Import(Stream input);
}
这是单元测试:
[TestMethod]
public void ImportProvider_Test()
{
// Arrange
var importRepository = new Mock<IImportRepository>();
var imp = new ImportProvider(importRepository.Object);
//Do setup...
// Act
var test_Stream = ?????????????
// This working but not option:
//test_Stream = File.Open("C:/ExcelFile.xls", FileMode.Open, FileAccess.Read);
var result = imp.Import(test_Stream);
// Assert
Assert.IsTrue(result);
}
使用内存流。不确定您的函数期望什么,但是例如将 UTF-8 字符串填充到其中:
//Act
using (var test_Stream = new MemoryStream(Encoding.UTF8.GetBytes("whatever")))
{
var result = imp.Import(test_Stream);
// Assert
Assert.IsTrue(result);
}
编辑:如果您需要一个 Excel 文件,并且您无法从磁盘读取文件,您可以将 Excel 文件作为嵌入式资源添加到您的测试项目中吗?请参见如何使用 Visual C# 嵌入和访问资源
然后您可以像这样阅读流:
//Act
using (var test_Stream = this.GetType().Assembly.GetManifestResourceStream("excelFileResource"))
{
var result = imp.Import(test_Stream);
// Assert
Assert.IsTrue(result);
}
您可以使用 MemoryStream 为您的测试提供纯内存流。
我的解决方案是将
Stream
包装在您自己的类中,让我们将其命名为StreamWrapper
,它实现了接口IStream
。现在将导入签名更改为
public bool Import(IStream stream)
现在您可以模拟该流,如果您想在生产代码中使用它,您应该通过
StreamWrapper
否则 Mock.
如果您正在对接受网络流、http 流、AWS S3 流和其他“不可搜索”流的代码进行单元测试,那么使用
MemoryStream
不是您最好的主意,因为它是“可搜索”的。
即它太温柔了,并且允许各种操作。
为了对与这些“粗糙”流一起工作的代码进行战斗测试,接近现实生活条件,我建议从 MemoryStream 继承,然后覆盖不支持)等等等等
现实生活中的例子:我正在使用一个图像处理库,它接受.CanSeek
作为输入。我的测试运行良好,因为它们基于 MemoryStreams 和 FileStreams。但是一旦我将我的代码部署到我处理来自 Amazon S3 的图像的生产环境中,我就会遇到各种异常,因为图像库需要一个可搜索的流。这是我使用的代码:
.Length
使用 JustMock、TypeMock 或 Microsoft Fakes 等隔离框架,您将能够模拟 Stream。
坏消息是,据我所知,他们都是有偿的。