我正在尝试编写一个函数:
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对象,但没有找到类似的东西。有人有什么建议吗?
答案 0 :(得分:4)
使用JarInputStream代替JarFile。为了进行测试,将JarInputStream挂钩到加载了内存中jar数据的ByteArrayInputStream,并在正常操作中将其挂接到文件的输入流。
答案 1 :(得分:0)
您可以使用EasyMock创建类JarFile的模拟对象。对于模拟对象,您可以指定在测试中调用哪些方法以及返回值是什么,而无需在文件系统上实际创建JAR文件。
然后使用模拟JarFile实例调用getTestXml()方法。
需要一些时间来适应它,但是你会发现这是值得的。
<强>更新强> 给定的源代码无法编译,因此这是一个可编译的版本:
public class JarFileUser {
public Map<String, Document> getTestXml(JarFile jarFile) throws IOException, ParserConfigurationException, SAXException {
Map<String, Document> result = new HashMap<String, Document>();
Enumeration<JarEntry> jarEntries = jarFile.entries();
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 = jarFile.getInputStream(jarFile.getJarEntry(testXmlFilename));
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document testXmlDocument = documentBuilder.parse(testXmlInputStream);
result.put(testClassName, testXmlDocument);
}
}
return result;
}
}
以下是EasyMock的测试:
public class JarFileUserTest {
private JarFile mockJarFile;
private Enumeration<JarEntry> mockJarEntries;
private JarFileUser jarFileUser;
private JarEntry first;
private JarEntry second;
private JarEntry firstXml;
@Before
public void setUp() throws Exception {
jarFileUser = new JarFileUser();
// Create a mock for the JarFile parameter
mockJarFile = createMock(JarFile.class);
// User Vector to provide an Enumeration of JarEntry-Instances
Vector<JarEntry> entries = new Vector<JarEntry>();
first = createMock(JarEntry.class);
second = createMock(JarEntry.class);
entries.add(first);
entries.add(second);
expect(first.getName()).andReturn("mocktest.JarFileUser.class");
expect(second.getName()).andReturn("mocktest.Ignore$Me.class");
mockJarEntries = entries.elements();
expect(mockJarFile.entries()).andReturn(mockJarEntries);
// JarEntry for the XML file
firstXml = createMock(JarEntry.class);
expect(mockJarFile.getJarEntry("TEST-mocktest.JarFileUser.xml")).andReturn(firstXml);
// XML contents
ByteArrayInputStream is = new ByteArrayInputStream("<test>This is a test.</test>".getBytes("UTF-8"));
expect(mockJarFile.getInputStream(firstXml)).andReturn(is);
replay(mockJarFile);
replay(first);
replay(second);
replay(firstXml);
}
@Test
public void testGetTestXml() throws IOException, ParserConfigurationException, SAXException {
Map<String, Document> map = jarFileUser.getTestXml(mockJarFile);
verify(mockJarFile);
verify(first);
verify(second);
verify(firstXml);
assertEquals(1, map.size());
Document doc = map.get("mocktest.JarFileUser");
assertNotNull(doc);
final Element root = (Element) doc.getDocumentElement();
assertNotNull(root);
assertEquals("test", root.getNodeName());
assertEquals("This is a test.", root.getTextContent());
}
}
关于其他库的说明 JarFile是一个类,而不是一个接口,所以根据EasyMock installation docs,你的类路径中应该有Objenesis和cglib。
答案 2 :(得分:0)
您需要查看ByteArrayOutputStream和ByteArrayInputStream。这些是Java中的内存流对象。使用这些,没有任何东西会写入磁盘。
答案 3 :(得分:0)
File()对象都存在于某个文件系统名称空间中。这为您提供了两个基本选择:
1)。如果您正在使用带有tempfs文件系统的O / S,请在那里创建它。 2)。使用File.createTempFile()并设置delete-on-exit属性。
创建子类的常用方法(“public MemoryFile extends File”...)不起作用,因为File()对象不包含执行实际I / O的方法,只是为了保存对象的名称和执行一些文件系统操作。