如何创建内存中的 JarFile?
我正在尝试编写一个如下函数:
public Map<String, Document> getTestXml(JarFile jarFile) {
Map<String, Document> result = Maps.newHashMap();
Enumeration<JarEntry> jarEntries = jarFile.getEntries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String name = jarEntry.getName();
if (name.endsWith(".class") && !name.contains("$")) {
String testClassName = name.replace(".class", "").replace("/", ".");
String testXmlFilename = "TEST-" + testClassName + ".xml";
InputStream testXmlInputStream = testJarFile.getInputStream(
testJarFile.getJarEntry(testXmlFilename));
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document testXmlDocument = documentBuilder.parse(testXmlInputStream);
result.put(testClassName, testXmlDocument);
}
}
return result;
}
我想编写一个单元测试,该测试实际上并不在文件系统上创建 JarFile。我试图寻找如何在内存中创建 File 对象,但没有找到类似的东西。有人有什么建议吗?
I'm trying to write a function like:
public Map<String, Document> getTestXml(JarFile jarFile) {
Map<String, Document> result = Maps.newHashMap();
Enumeration<JarEntry> jarEntries = jarFile.getEntries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String name = jarEntry.getName();
if (name.endsWith(".class") && !name.contains("$")) {
String testClassName = name.replace(".class", "").replace("/", ".");
String testXmlFilename = "TEST-" + testClassName + ".xml";
InputStream testXmlInputStream = testJarFile.getInputStream(
testJarFile.getJarEntry(testXmlFilename));
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document testXmlDocument = documentBuilder.parse(testXmlInputStream);
result.put(testClassName, testXmlDocument);
}
}
return result;
}
And I would like to write a unit test that doesn't actually create a JarFile on the file system. I've tried to look for how to create a File object in memory, but haven't found anything like that. Anyone have any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用 JarInputStream 代替 JarFile。为了进行测试,将 JarInputStream 连接到加载了内存中 jar 数据的 ByteArrayInputStream,并在正常操作中将其连接到文件的输入流。
Instead of a JarFile, use a JarInputStream. For testing, hook the JarInputStream up to a ByteArrayInputStream loaded with in-memory jar data, and in normal operation hook it up to the input stream from a file.
File() 对象都存在于某个文件系统名称空间中。这给了你两个基本选择:
1)。如果您使用带有 tempfs 文件系统的操作系统,请在那里创建它。
2)。使用 File.createTempFile() 并设置退出时删除属性。
创建子类的常用方法(“public MemoryFile extends File”...)不起作用,因为 File() 对象不包含执行实际 I/O 的方法,仅用于保存该子类的名称对象并执行一些文件系统操作。
File() objects all live within some file system name space. Which gives you two basic choices:
1). If you're using an O/S with a tempfs file system, create it there.
2). Use File.createTempFile() and set the delete-on-exit attribute.
The usual approach of creating a sub-class ("public MemoryFile extends File" ...) doesn't work because a File() object doesn't contain the methods for doing actual I/O, just for holding the name of the object and doing a few file system operations.
您需要查看 ByteArrayOutputStream 和 ByteArrayInputStream。这些是 Java 中的内存流对象。使用它们,什么都不会写入磁盘。
You need to look at ByteArrayOutputStream and ByteArrayInputStream. Those are the in memory stream objects in Java. Use those and nothing will get written to disk.
您可以使用 EasyMock 创建 JarFile 类的模拟对象。对于模拟对象,您可以指定在测试中调用哪些方法以及返回值是什么,而无需在文件系统上实际创建 JAR 文件。
然后使用模拟 JarFile 实例调用 getTestXml() 方法。
它需要一些时间来适应,但随后你就会发现这是值得的。
更新
给定的源代码无法编译,因此这里是一个可编译的版本:
这是使用 EasyMock 进行的测试:
有关附加库的注意事项
JarFile 是一个类,而不是一个接口,因此根据 EasyMock 安装文档,您应该有 Objenesis 和 cglib 在你的类路径中。
You can use EasyMock to create a mock object of class JarFile. For the mock object you specify which methods are called in the test and what the return values are without the need to actually create a JAR file on the file system.
Then call your getTestXml() method with your mock JarFile instance.
It needs some time to get used to it, but then you will see it's worth the effort.
Update
The given source code doesn't compile, so here is a compilable version:
Here is a test with EasyMock:
Note on additional libraries
JarFile is a class and not an interface so according to the EasyMock installation docs you should have Objenesis and cglib in your classpath.