我使用Visual Studio 2008 Professional自动化测试。我有一个写入文件的函数。我想单元测试文件写入功能。我已经读过某个地方,我不得不以某种方式模拟文件。我不知道怎么做。你能帮忙吗?
如何对从Internet下载页面的方法进行单元测试?
答案 0 :(得分:7)
如果方法必须打开文件流本身,那么很难模拟。但是,如果您可以将流传递给方法,并使其写入该方法,则可以传入MemoryStream。替代重载可以占用更少的参数,打开文件并将FileStream传递给另一个方法。
通过这种方式,您无法获得完整的覆盖率(除非您编写了一个或两个确实命中磁盘的测试)但是大多数逻辑都在完全测试的代码中,在采用Stream参数的方法中。
答案 1 :(得分:6)
这取决于你的代码与nut'n'bolts的接近程度;例如,您可以在Stream
中工作,并将MemoryStream
传递给代码(并检查内容)。您可以只写入文件系统(在临时区域中),检查内容并在之后丢弃它。如果您的代码略高于文件系统,那么您可以使用所需的高级方法(如IFileSystem
/ WriteAllBytes
)编写一个可模拟的WriteAllText
接口。但是,模拟流API会很痛苦。
从互联网下载(或假装)...你可以(例如)用你需要的功能(如IWebClient
等)写一个DownloadString
界面;嘲笑它返回固定内容,并使用WebClient
之类的东西作为实际实现的基础。当然,您需要针对真实站点测试实际实现。
答案 2 :(得分:4)
如果测试的目标是测试文件是否实际创建,则它是集成测试,而不是单元测试。
如果目标是测试正确写入文件的内容,则隐藏接口后面的文件访问权限,并提供内存实现。
网页访问也是如此。
interface IFileService
{
Stream CreateFile(string filename);
}
class InMemoryFileService : IFileService
{
private Dictionary<string, MemoryStream> files = new Dictionary<string, MemoryStream>();
public Stream CreateFile(string filename)
{
MemoryStream stream = new MemoryStream();
files.Add(filename, stream);
return stream;
}
public MemoryStream GetFile(string filename)
{
return files[filename];
}
}
使用GetFile,您可以找到应该写入磁盘的内容。
答案 3 :(得分:1)
您实际上并不想直接在函数中调用文件,而是将文件I / O包装在带有接口的类中。
然后,您可以使用Rhino Mocks之类的东西来创建实现该接口的模拟类。