我想测试一个使用方法File.OpenRead()
来获取文件内容的类。在读取文件的内容后,它会处理它们。我创建了一个接口和一个包装静态OpenRead()
方法的类。但是我遇到OpenRead()
返回FileStream
但我不知道如何“模拟”文件流的问题。
目前,我正在创建一个文件,只是为了创建一个FileStream
...当然,测试经常会失败IOException
,因为该文件仍在使用中......
剥离示例: 类:
class FileProcessor
{
public FileProcessor(IFileWrap fileWrap) // fileWrap only redirects the calls to the static methods of File class
{ ... }
public void Process(string file)
{
var content = fileWrap.ReadAllLines(file);
// process content
}
}
测试:
[TestClass]
public class FileProcessor_Test
{
[TestMethod]
Process_FileNotReadable_Exception()
{
File.WriteAllText(testFile, "something");
var fileWrapMock = new Mock<IFileWrap>();
FileProcessor dut = new FileProcessor(fileWrapMock.Object);
var actualException = AssertException.Throws<Exception>(() => dut.Process(testFile));
}
}
我也想避免创建FileStream
的抽象。
我希望我可以创建一个MemoryStream
并以某种方式将其用作输入,但这需要更改文件包装并偏离实际的File
类。
赞赏任何意见:)
编辑:
处理包括通过从类ComputeHash()
调用MD5
来计算MD5校验和。
答案 0 :(得分:4)
您的原始方法与它在文件上运行的事实紧密相关。不要这样做。使方法采用Stream
,任何流。您可以使用FileStream
进行操作,也可以通过MemoryStream
进行测试。
public void Process(string file)
应该是
public void Process(Stream stream)
如果您愿意,为方便起见,您可能会有第二个方法重载:
public void Process(string file)
{
using (var stream = new FileStream(file, FileMode.Open))
{
this.Process(stream);
}
}
确实不能也不应该进行单元测试......它的.NET代码处理外部资源,在某些时候你必须信任框架。
要解决您的编辑问题:大多数Framework类都做类似的事情,例如MD5类有一个适用于流的ComputeHash方法。
答案 1 :(得分:2)
首先,您不需要进行单元测试&#39;文件&#39;作为&#39; OpenRead&#39;是一个静态的方法&#39; File&#39;你无法解耦的阶级。对任何具有依赖性的东西编写单元测试并不理想。在你的情况下,你可以模拟&#39; IFileWrap&#39;并为'ReadAllLines&#39;创建一个模拟方法。当单元测试命中&fileWrap.ReadAllLines(文件)&#39;它会调用mock方法而不是去#File; Openpen()&#39;方法
答案 2 :(得分:1)
我建议你让IFileWrap返回一个字符串(读取所有行)而不是MemoryStream。基本上,可以在File上创建一个抽象,将File封装在其中。