如何使用JUnit测试SAX解析器的结果?

时间:2014-02-17 08:58:37

标签: xml junit

我创建了一个XML解析器来解析一些xml配置文件。解析器的结果是在回调侦听器中返回,如下所示:

interface OnParseResultListener {
    void onFinished(Result result);
}

解析器用于通过传入xml文件路径和监听器来获取Result对象:

MyParser parser = new MyParser();
parser.parse("conf.xml", new OnParseResultListener(){
    void onFinished(Result result) {
        // get the Result object here
    }
});

现在我想编写JUnit代码来测试MyParser是否运行良好。但是当我将上面的代码放在测试方法中时,测试方法总是在调用onFinished()之前终止。

我在调用wait()后尝试使用parse(),并在解析完成时在notify()中使用onFinished(),但它一直等待。我的猜测是JUnit线程被阻止,但SAX XMLReader需要向该线程发送事件,因此它无法通过。

所以我无法阻止JUnit线程,但它在解析完成之前就结束了。我该怎么做才能测试解析结果?

MyParser看起来大致如下:

public class MyParser {
    OnParserResultListener listener;
    public void parse(InputStream xml, OnParserResultListener listener) {
        this.listener = listener;
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser;
        try {
            parser = factory.newSAXParser();
            XMLReader xmlReader = parser.getXMLReader();

            //handle xml parsing events in a customized BaseHandler
            xmlReader.setContentHandler(new BaseHandler());

            InputSource is = new InputSource(xml);
            xmlReader.parse(is);
        } catch (Exception e) {} 
    }
}

class BaseHandler extends DefaultHandler {
    public void startElement(String u, String l, String q, Attributes a) {
        .... //handle xml tag
    }

    public void endElement(String r, String l, String q) throws SAXException {
        .... //read xml value, save to a Result object

        //return the Result object via OnParserResultListener's callback method
        this.listener.onFinished(Result);
    }
    ....//other methods
}

1 个答案:

答案 0 :(得分:0)

在回调中需要一个锁定机制,以便在传递结果时将调用线程置于保持状态。

如果永远不会触发回调,您还希望超时测试。以下内容应该有效:

@Test(timeout = 5000) 
public void receivesResultsFromParser() {
    final Semaphore latch = new Semaphore(1);
    new Thread(new Runnable() {
       public void run() {
           MyParser parser = new MyParser(); 
           parser.parse("conf.xml", new OnParseResultListener(){
               void onFinished(Result result) {
                   // do result validation here
                   latch.release();
               }
           });
        }
     }).start();

     latch.acquire();
}