使用Shims for ZipFile进行unit testing

我正在尝试对使用ZipFile.OpenRead的一些代码进行unit testing,从ZIP中提取一些XML文件(用moq编写unit testing)

有没有办法用我自己的结果替换对ZipFile.OpenRead的调用? 我已经在类似的情况下使用垫片,但我无法弄清楚在这种情况下该做什么,并且关于垫片的文档非常稀疏。

这是(部分)需要unit testing的方法:

public IEnumerable ExtractXmlFromZip(string fileName) { var configs = new List(); using (var archive = ZipFile.OpenRead(fileName)) { foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) { LoadConfigfromZipArchiveEntry(entry, configs) } } } return configs; } 

没有办法使用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 ExtractXmlFromZip(string fileName) { var configs = new List(); // 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(); mockWrapper.Setup(m => m.OpenRead(fileName)).Returns(myZipArchive); var configs = myThing.ExtractXmlFromZip(fileName); // Assert } } 

您可能需要包含更多以获得该传递,但希望这显示了该概念。


(在我意识到这是你要求的moq并且不是来自Microsoft Fakes的垫片之前写了这个)
有一种更简单的方法可以使用可以获得此代码的Shims – 来自Microsoft Fakes。 ZipFile类是System.IO.Compression.FileSystem一部分,它位于同名的dll中。

为了让我们使用ShimZipFile ,我们需要添加一个ShimZipFile Assembly:

注意:我们需要Fake 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 } } 

MSDN上有关于伪造生成的填充程序的命名约定的信息。

我最近采用的方法之一是在类上使用私有委托成员,其目的是包装具体实现。

幸运的是,对我来说,R#可以很容易地创建一个具有单个私有成员的具体代理类,在包装类型上公开公共成员(通过Delegate Members代码生成器),然后提取接口以解耦,并提供模拟方法,并在测试期间进行validation。