单元测试使用垫片的使用ZipFile [英] Unit Testing using Shims for ZipFile
问题描述
我试图单元测试一些代码,使用内ZipFile.OpenRead从ZIP提取一些XML文件(编写单元测试与MOQ)
时有没有一种方法可以取代我自己的结果调用ZipFile.OpenRead?我已经使用垫片类似的情况,但我无法弄清楚如何在这种情况下和文献垫片做的是相当稀少。
下面是(部分)需要单元测试方法:
公开的IEnumerable< ConfigurationViewModel> ExtractXmlFromZip(字符串文件名)
{
变种CONFIGS =新的List< ConfigurationViewModel>();使用
(VAR存档= ZipFile.OpenRead(文件名))
{
的foreach(ZipArchiveEntry在archive.Entries项)
{
如果(entry.FullName.EndsWith (名为.xml,StringComparison.OrdinalIgnoreCase))
{
LoadConfigfromZipArchiveEntry(入门,CONFIGS)
}
}
}
返回CONFIGS;
}
有没有一种方法使用模拟嘲笑像ZipFile的一个静态类,你会使用IZipFileWrapper(说)
要么把它包
公共IZipFileWrapper
{
ZipArchive打开读取(字符串文件名)
}
公共ZipFileWrapper:IZipFileWrapper
{
公共ZipArchive打开读取(字符串文件名)
{
返回ZipFile.OpenRead(文件名)
}
}
然后代码变为:
公共MyObj中
{
私人IZipFileWrapper zipFileWrapper;
公共MyObj中(IZipFileWrapper zipFileWrapper)
{
this.zipFileWrapper = zipFileWrapper;
}
公开的IEnumerable< ConfigurationViewModel> ExtractXmlFromZip(字符串文件名)
{
变种CONFIGS =新的List< ConfigurationViewModel>();
//使用呼叫包装
(VAR存档= this.zipFileWrapper.OpenRead(文件名))
{
的foreach(在archive.Entries ZipArchiveEntry项)
{
如果(entry.FullName.EndsWith(XML,StringComparison.OrdinalIgnoreCase))
{
LoadConfigfromZipArchiveEntry(入门,CONFIGS)
}
}
}
返回CONFIGS;
}
}
和
$ B $的考验b [TestMethod的]
公共无效ExtractXmlFromZip_Test()
{
变种myThing =新MyObj中();
变种文件名=my.zip;
ZipArchive myZipArchive = CreateTestZipFile(); //设置你回来
变种mockWrapper =新的模拟< IZipFileWrapper>();
mockWrapper.Setup(M = GT; m.OpenRead(文件名)),返回(myZipArchive);
VAR CONFIGS = myThing.ExtractXmlFromZip(文件名);
//断言
}
}
您可能会需要包装更获得了通过,但希望显示的概念。
(写到这之前,我意识到这是MOQ你被询问,而不是从微软正版正货垫片)
有使用垫片,能够得到这个代码更简单的方法 - 从微软假货。
中的的ZipFile 类是
System.IO.Compression.FileSystem
的一部分,这是在同一个名字的DLL。 要我们使用 ShimZipFile
,我们需要添加一个假货大会:
请注意:我们需要假 System.IO.Compression.FileSystem
(即DLL)的不可以 System.IO.Compression
dlll(即的ZipFile
的命名空间)
哪些应该进行以下修改项目:
然后,我们可以用它在测试中,如:
[TestMethod的]
公共无效ExtractXmlFromZip_Test()
{
VAR myThing =新MyObj中();
变种文件名=my.zip;
ZipArchive myZipArchive = CreateTestZipFile(); //设置使用返回
(ShimsContext.Create())
{
System.IO.Compression.Fakes.ShimZipFile.OpenReadString =(文件名)=> myZipArchive;
VAR CONFIGS = myThing.ExtractXmlFromZip(文件名);
//断言
}
}
有信息上MSDN有关命名约定的为假货产生垫片。
I'm attempting to unit test some code that use ZipFile.OpenRead within to extract some XML files from a ZIP (Writing the unit tests with moq)
Is there a way I can replace the call to ZipFile.OpenRead with my own result? I have used shims for similar situations, but I can't figure out what to do in this situation and documentation on shims is pretty sparse.
Here is (part of) the method that needs unit-testing:
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;
}
There isn't a way to mock a static class like ZipFile using mock, you would either wrap it using an IZipFileWrapper (say)
public IZipFileWrapper
{
ZipArchive OpenRead(string fileName)
}
public ZipFileWrapper : IZipFileWrapper
{
public ZipArchive OpenRead(string fileName)
{
return ZipFile.OpenRead(fileName)
}
}
Then the code becomes:
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;
}
}
And a test of
[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
}
}
You would probably need to wrap more to get that passing, but hopefully that shows the concept.
(wrote this before I realised it was moq you were asking about and not shims from Microsoft Fakes)
There is an easier way to use Shims that can get to this code - from Microsoft Fakes. The ZipFile class is part of
System.IO.Compression.FileSystem
, which is in the dll of the same name.
To let us use a ShimZipFile
, we need to add a Fakes Assembly:
Note: We need to Fake System.IO.Compression.FileSystem
(i.e. the dll) not System.IO.Compression
dlll (which is the namespace of ZipFile
).
Which should make the following changes to the project:
Then we can use it in a test such as:
[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
}
}
There is info on MSDN about the naming conventions for shims that fakes generates.
这篇关于单元测试使用垫片的使用ZipFile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!