嘲笑 File.OpenWrite()
Mocking File.OpenWrite()
我正在尝试编写一个单元测试,该测试写入一个用 File.OpenWrite() 打开的文件。
我正在使用 SystemWrapper 的 IFileWrap 接口包装文件。在生产中,我使用 SimpleInjector 注入 SystemWrapper 的 FileWrap class 的一个实例,并且工作正常。但我试图在我的单元测试中模拟 IFileWrap,使用最小起订量,但这不起作用。
我是 SystemWrapper 的新手,我正在尽最大努力了解它的用途。据我所知,IFileWrap.OpenWrite() returns 一个 IFileWrap 实例,您可以从中获取带有 FileStreamInstance 的流。
因此,在我的 class 测试中,我在构造函数中注入了一个 IFileWrap:
public class ClassUnderTest
{
private readonly IFileWrap fileWrap;
public ClassUnderTest(IFileWrap fileWrap)
{
this.fileWrap = fileWrap;
}
...
}
在我的测试方法中,我从 FileStreamInstance 获取流:
var fsWrap = this.fileWrap.OpenWrite(fullPath);
var ostream = fswrap.FileStreamInstance;
这在生产中运行良好,其中 fileWrap 是使用 FileWrap 实例实例化的。但是在我的测试中,我正在尝试为
File.OpenWrite returns 模拟的 FileStream:
var fileStreamMock = new Mock<IFileStreamWrap>();
var fileMock = new Mock<IFileWrap>();
fileMock.Setup(fm => fm.OpenWrite(It.IsAny<string>())).Returns(fileStreamMock.Object);
var classUnderTest = new ClassUnderTest(fileMock.Object);
当我在调试器中遍历被测试的方法时,从我的单元测试中,fsWrap.FileStreamInstance 为 null,而我希望它是我的模拟文件流。
关于我做错了什么有什么想法吗?
您没有将 FileStreamInstance
存根到 return 任何东西,因此最小起订量将 return 为空。
创建 IFileStreamWrap
mock 后,您需要为 FileStreamInstance
设置 return 一些东西:
var fileStreamWrapMock = new Mock<IFileStreamWrap>(); // Was fileStreamMock
var fileStreamMock = new Mock<FileStream>();
fileStreamWrapMock.Setup(fswm => fswm.FileStreamInstance).Returns(fileStreamMock);
最近我一直在为这个问题苦苦挣扎。正如您在 的评论中所建议的那样,我最初通过使用临时文件解决了它。我最近偶然发现了另一种方式,使用 StreamInstance 而不是 FileStreamInstance (当你提出问题时不确定这是否可用):
var outBuffer = new byte[512];
var fileWrap = new Mock<IFileWrap>();
var fileStreamWrap = new Mock<IFileStreamWrap>();
var stream = new Mock<IFileStreamWrap>();
fileStreamWrap.Setup(fsw => fsw.StreamInstance).Returns(new MemoryStream(outBuffer));
//I'm using File.Create to create temporary files with DeleteOnClose flag in the application, which get disposed before the function returns
fileWrap.Setup(fw => fw.Create(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<FileOptions>()))
.Returns((string filepath, int i, FileOptions fo) =>
{
//I'm using filepath in a collection in my test to handle multiple files created in the application code
return fileStreamWrap.Object;
});
//Call application code that creates temporary file and closes eagerly with dispose.
//Application code will be something like:
var tempFileStream = _fileWrap.Create(tempFileName, 4096, FileOptions.DeleteOnClose);
using (var writer = new StreamWriter(tempFileStream.StreamInstance, Encoding.Default, 4096, true))
{...}
//Test file contents were written correctly into outBuffer
var outString = System.Text.Encoding.UTF8.GetString(outBuffer);
Assert.AreEqual("Important Business string", outString);
我正在尝试编写一个单元测试,该测试写入一个用 File.OpenWrite() 打开的文件。
我正在使用 SystemWrapper 的 IFileWrap 接口包装文件。在生产中,我使用 SimpleInjector 注入 SystemWrapper 的 FileWrap class 的一个实例,并且工作正常。但我试图在我的单元测试中模拟 IFileWrap,使用最小起订量,但这不起作用。
我是 SystemWrapper 的新手,我正在尽最大努力了解它的用途。据我所知,IFileWrap.OpenWrite() returns 一个 IFileWrap 实例,您可以从中获取带有 FileStreamInstance 的流。
因此,在我的 class 测试中,我在构造函数中注入了一个 IFileWrap:
public class ClassUnderTest
{
private readonly IFileWrap fileWrap;
public ClassUnderTest(IFileWrap fileWrap)
{
this.fileWrap = fileWrap;
}
...
}
在我的测试方法中,我从 FileStreamInstance 获取流:
var fsWrap = this.fileWrap.OpenWrite(fullPath);
var ostream = fswrap.FileStreamInstance;
这在生产中运行良好,其中 fileWrap 是使用 FileWrap 实例实例化的。但是在我的测试中,我正在尝试为 File.OpenWrite returns 模拟的 FileStream:
var fileStreamMock = new Mock<IFileStreamWrap>();
var fileMock = new Mock<IFileWrap>();
fileMock.Setup(fm => fm.OpenWrite(It.IsAny<string>())).Returns(fileStreamMock.Object);
var classUnderTest = new ClassUnderTest(fileMock.Object);
当我在调试器中遍历被测试的方法时,从我的单元测试中,fsWrap.FileStreamInstance 为 null,而我希望它是我的模拟文件流。
关于我做错了什么有什么想法吗?
您没有将 FileStreamInstance
存根到 return 任何东西,因此最小起订量将 return 为空。
创建 IFileStreamWrap
mock 后,您需要为 FileStreamInstance
设置 return 一些东西:
var fileStreamWrapMock = new Mock<IFileStreamWrap>(); // Was fileStreamMock
var fileStreamMock = new Mock<FileStream>();
fileStreamWrapMock.Setup(fswm => fswm.FileStreamInstance).Returns(fileStreamMock);
最近我一直在为这个问题苦苦挣扎。正如您在
var outBuffer = new byte[512];
var fileWrap = new Mock<IFileWrap>();
var fileStreamWrap = new Mock<IFileStreamWrap>();
var stream = new Mock<IFileStreamWrap>();
fileStreamWrap.Setup(fsw => fsw.StreamInstance).Returns(new MemoryStream(outBuffer));
//I'm using File.Create to create temporary files with DeleteOnClose flag in the application, which get disposed before the function returns
fileWrap.Setup(fw => fw.Create(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<FileOptions>()))
.Returns((string filepath, int i, FileOptions fo) =>
{
//I'm using filepath in a collection in my test to handle multiple files created in the application code
return fileStreamWrap.Object;
});
//Call application code that creates temporary file and closes eagerly with dispose.
//Application code will be something like:
var tempFileStream = _fileWrap.Create(tempFileName, 4096, FileOptions.DeleteOnClose);
using (var writer = new StreamWriter(tempFileStream.StreamInstance, Encoding.Default, 4096, true))
{...}
//Test file contents were written correctly into outBuffer
var outString = System.Text.Encoding.UTF8.GetString(outBuffer);
Assert.AreEqual("Important Business string", outString);