我试图对使用ZipFile.OpenRead的一些代码进行单元测试,从ZIP中提取一些XML文件(用moq编写单元测试)
有没有办法用我自己的结果替换对ZipFile.OpenRead的调用?我已经在类似的情况下使用垫片,但是我无法弄清楚在这种情况下该做什么,并且有关垫片的文档非常稀疏。
以下是需要进行单元测试的方法(部分):
public IEnumerable<ConfigurationViewModel> ExtractXmlFromZip(string fileName)
{
var configs = new List<ConfigurationViewModel>();
using (var archive = ZipFile.OpenRead(fileName))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
{
LoadConfigfromZipArchiveEntry(entry, configs)
}
}
}
return configs;
}
答案 0 :(得分:2)
没有办法使用mock模拟像ZipFile这样的静态类,你可以使用IZipFileWrapper(比如说)来包装它
public IZipFileWrapper
{
ZipArchive OpenRead(string fileName)
}
public ZipFileWrapper : IZipFileWrapper
{
public ZipArchive OpenRead(string fileName)
{
return ZipFile.OpenRead(fileName)
}
}
然后代码变为:
public MyObj
{
private IZipFileWrapper zipFileWrapper;
public MyObj(IZipFileWrapper zipFileWrapper)
{
this.zipFileWrapper = zipFileWrapper;
}
public IEnumerable<ConfigurationViewModel> ExtractXmlFromZip(string fileName)
{
var configs = new List<ConfigurationViewModel>();
// Call the wrapper
using (var archive = this.zipFileWrapper.OpenRead(fileName))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
{
LoadConfigfromZipArchiveEntry(entry, configs)
}
}
}
return configs;
}
}
和
的测试[TestMethod]
public void ExtractXmlFromZip_Test()
{
var myThing = new MyObj();
var fileName = "my.zip";
ZipArchive myZipArchive = CreateTestZipFile(); // Set up your return
var mockWrapper = new Mock<IZipFileWrapper>();
mockWrapper.Setup(m => m.OpenRead(fileName)).Returns(myZipArchive);
var configs = myThing.ExtractXmlFromZip(fileName);
// Assert
}
}
你可能需要包装更多以获得该传递,但希望这显示了这个概念。
<小时/> (在我意识到这是你要求的moq并且不是来自Microsoft Fakes的垫片之前写过这个)
System.IO.Compression.FileSystem
的一部分,它位于同名的dll中。
要让我们使用ShimZipFile
,我们需要添加一个Fakes Assembly:
注意:我们需要伪造System.IO.Compression.FileSystem
(即dll)不 System.IO.Compression
dlll(ZipFile
的名称空间)。
应该对项目进行以下更改:
然后我们可以在以下测试中使用它:
[TestMethod]
public void ExtractXmlFromZip_Test()
{
var myThing = new MyObj();
var fileName = "my.zip";
ZipArchive myZipArchive = CreateTestZipFile(); // Set up your return
using (ShimsContext.Create())
{
System.IO.Compression.Fakes.ShimZipFile.OpenReadString = (filename) => myZipArchive;
var configs = myThing.ExtractXmlFromZip(fileName);
// Assert
}
}
答案 1 :(得分:0)
我最近采用的一种方法是在类上使用私有委托成员,其目的是包装具体实现。
幸运的是,对我来说,R#可以很容易地创建一个具有单个私有成员的具体代理类,在包装类型上公开公共成员(通过Delegate Members代码生成器),然后提取接口以解耦,并提供在测试过程中模拟和验证的方法。