3

私は次のような関数を書こうとしています:

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

4 に答える 4

4

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

于 2011-07-05T23:15:10.063 に答える
1

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

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

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

于 2011-07-05T23:17:54.870 に答える
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 のインストール ドキュメントによると、クラスパスにObjenesiscglibを含める必要があります。

于 2011-07-05T23:09:30.023 に答える
0

ByteArrayOutputStreamByteArrayInputStreamを見る必要があります。これらは、Javaのインメモリストリーム オブジェクトです。それらを使用すると、ディスクには何も書き込まれません。

于 2011-07-05T23:16:28.933 に答える