2011-07-05 8 views
3

私は次のように関数を記述しようとしています:メモリ内のJarファイルを作成するには?

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オブジェクトを作成する方法を探してみましたが、そのようなものは見つかりませんでした。誰でも何か提案がありますか?

答えて

4

JarFileの代わりに、JarInputStreamを使用します。テストのために、JarInputStreamをメモリ内のjarデータでロードされたByteArrayInputStreamまでフックし、通常の操作でファイルからの入力ストリームに接続します。

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によれば、クラスパスにとcglibがあります。

+0

私は現在JMockitを使用しています。私がするJarFileをモックしようとすると、私が手:「メイン」java.lang.NoClassDefFoundErrorのスレッドで 例外:ORG/JUnitの/内部/ランナー/モデル/ MultipleFailureException あなたはEasyMockがするJarFileを処理することができますか? –

+0

はいEasyMockはJarFileを処理できます。私は自分の答えを更新しました。 – vanje

0

ByteArrayOutputStreamByteArrayInputStreamをご覧ください。それらはメモリ内ので、Javaのストリームオブジェクトはです。それらを使用すると、何もディスクに書き込まれません。

0

File()オブジェクトはすべて、ファイルシステムの名前空間内に存在します。あなたには2つの基本的な選択肢があります:

1)。 tempfsファイルシステムでO/Sを使用している場合は、そこに作成してください。 2)。 File.createTempFile()を使用して、exit-delete属性を設定します。

File()オブジェクトには実際のI/Oを実行するためのメソッドが含まれていないため、サブクラス(「public MemoryFile extends File ... ...」)を作成する通常の方法は機能しませんオブジェクトの名前といくつかのファイルシステム操作を行います。

+0

上記のJarInputStreamの回答に関しては、その方法が有効ですが、Jarを作成するにはJarOutputStreamを使用する必要があります。オブジェクトのペアを渡すことが気にならないように、JarInputStreamとJarOutputStreamを常に使用するようにコードを再実行することは解決策になります。 JarFileを使用するには、一時ファイルを作成する必要があります。 – tallgirl

関連する問題