Posts Tagged ‘Emma’

Striving for Unit Tests with 100% Coverage

October 9, 2010

I’ve found Emma to provide some real insight into what is actually getting tested.  While trying to bolster a suite to 100% coverage that I had though was pretty good already (it was ~85%) it showed me an interesting problem.

I have a method that looked something like this:

public MyMessage parseXMLtoMyMessage( final Reader reader ) {
    MyMessage msg = null ;
    try {
        final JAXBContext context = JAXBContext.newInstance(MyMessage.class);
        final Unmarshaller u = context.createUnmarshaller();
        final SAXSource src = new SAXSource( new InputSource(reader) );
        msg = (MyMessage) u.unmarshal(src);
    } catch (JAXBException e) {
        e.printStackTrace(); // yes I do better exception handling than this...
    return msg ;
}

I can pass in any kind of  Reader I want to for my tests and the JAXB2 code is isolated in one area of responsibility.  This worked great until I found out the real  XML was coming in with a namespace (that fact is not in the provided message spec) and that namespace isn’t reachable… nice.

So, I needed to disable namespace checking.  A quick bit of research turns the method into the following (changes noted in red):
public MyMessage parseXMLtoMyMessage( final Reader reader ) {
    MyMessage msg = null ;
    try {
        final JAXBContext context = JAXBContext.newInstance(MyMessage.class);
        final Unmarshaller u = context.createUnmarshaller();
        final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
        xmlReader.setFeature("http://xml.org/sax/features/namespaces", false) ;
        final SAXSource src = new SAXSource( xmlReader, new InputSource(reader) );
        msg = (MyMessage) u.unmarshal(src);
    } catch (JAXBException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    }
    return msg ;
}

Emma had originally reported that there are no test paths through the exceptions.  OK, it is pretty easy to force the JAXBException by sending in an incomplete or otherwise improperly formatted XML stream. However, because of the need for the XMLReader to disable namespace checking I now have a SAXException that is generated completely internally to the parse method.  There’s no way to mock out the XMLReader without injecting it.  My options are:

  1. I can provide an injection point.  Sorry, no – I don’t think any client to the method should have to know about the namespace problem and exposing the XMLReader in any way amounts to that.
  2. I can alter the system property “org.xml.sax.driver” to point at something invalid,.  Unfortunately, also no.  That wrecks all other tests since I can’t return it to its original null value after the test and the tests shouldn’t be order dependent (i.e. try to make this the last test… of the entire suite).

So here I sit, unwilling to provide an injection point for XMLReader and unable to write a test to cover a specific branch.  I’m open to suggestions.