编写Junit测试,以便使用TransformerFactory在XML上应用XSLT

时间:2014-09-16 20:46:02

标签: java xml xslt junit

我是Junit Test的新手,我有一个xml文件和xslt文件如下:

File.xml

<people>
<person>
    <role>Parent</role>
    <lastname>Smith</lastname>
    <locations>
        <location>
            <city>Springfield</city>
            <state>MA</state>
            <unimportant-field>123</unimportant-field>
        </location>
        <location>
            <city>Chicago</city>
            <state>IL</state>
            <unimportant-field>456</unimportant-field>
        </location>
    </locations>
</person>
<person>
    <role>Child</role>
    <lastname>Smith</lastname>
    <locations>
        <location>
            <city>Springfield</city>
            <state>IL</state>
            <unimportant-field>789</unimportant-field>
        </location>
        <location>
            <city>Chicago</city>
            <state>IL</state>
            <unimportant-field>000</unimportant-field>
        </location>
        <location>
            <city>Washington</city>
            <state>DC</state>
            <unimportant-field>555</unimportant-field>
        </location>
    </locations>
</person>

XSLT文件如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="parent-location" match="person[role='Parent']/locations/location" use="concat(../../lastname, '|', city, '|', state)" />

<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="person[role='Child']/locations/location[not(key('parent-location', concat(../../lastname, '|', city, '|', state)))]"/>

</xsl:stylesheet>

这是我用来在XML上应用上述XSLT的java代码。

public class ApplyXSLT {
    /**
     * @param args
     * @throws TransformerException
     * @throws FileNotFoundException
     */
    public  void process()throws FileNotFoundException, TransformerException
    {
        InputStream file1 = new FileInputStream("file.xml");
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer transformer = tFactory.newTransformer(new StreamSource("file.xslt"));
        transformer.transform(new StreamSource(file1), new StreamResult(new FileOutputStream("output.xml")));

    }
}

如果有人可以指导我,我不知道如何为上述内容编写Junit测试。我会很感激。谢谢。

1 个答案:

答案 0 :(得分:0)

首先,建议您编写Junit测试来测试API实用程序。我的意思是,您应该首先编写一个完整的语义抽象代码:一个具有正确命名的方法,参数和返回值的类。标准方法main没有任何语义:你不知道它的作用(它的名字没有特定的含义),它不需要多少参数,也不知道它产生结果的位置。

所以,当你有这样的课时:

public class MyTransformer 
{
    public void transform(InputStream in, OutputStream out) 
    throws IOException, TransformException
    {...}
}
// If needed, You could also add a main method which delegates over the transform method.

...您可以像这样对Junit测试人员进行编码:

public class MyTransformerTest
{
    // Transforms an existing file producing the result in memory,
    // and compares it with an existing, expected output file.
    private void test(String inputFilename, String expectedOutputFilename)
        throws IOException
    {
        try
        {
            ByteArrayOutputStream out=new ByteArrayOutputStream();
            new MyTransformer().transform(new FileInputStream(inputFilename), out);
            String expectedResult=readFileAsString(expectedOutputFilename);
            assertEquals("File '" + inputFilename + "' was not transformed OK", expectedResult, out.toString("ISO-8859-1"));
        }
        catch (TransformerException e)
        {
            e.printStackTrace();
            fail(e.toString());
        }
    }

    @Test
    public void testEmpty()
        throws IOException
    {
        test("empty-input.xml", "empty-output.xml");
    }

    @Test
    public void testOnePersons()
        throws IOException
    {
        test("one-persons-input.xml", "one-persons-output.xml");
    }

    @Test
    public void testTwoPersons()
        throws IOException
    {
        test("two-persons-input.xml", "two-persons-output.xml");
    }
}

并非此测试程序基于测试任何文件的通用测试方法。因此,您只需为您感兴趣的每个案例编写一个输入文件和一个预期的输出文件。

这项技术将为您的测试人员的未来维护提供便利:Rembember,每当您发现错误时,首先您必须在测试仪中添加一种方法来重现它(其中最初将失败,科西嘉)。然后修复代码,再次运行测试仪,直到它没有失败。

还有一点需要注意:我通常将IOExceptions保留在throws子句中,而不会捕获它们。这是因为这个例外不是你的代码的错。所以,你的测试并不有意思。如果在测试程序执行时出现IOException,则意味着无法实例化输入或输出文件:在代码执行之前发生了