mercredi 7 septembre 2016

Using PowerMock with embedded Tomcat

I'm trying to mock a static method that is called by an embedded Tomcat instance. Here is my test class:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ExternalAPI.class)
@PowerMockIgnore({"javax.management.*"})
public class TestExternalAPI
{

    @Before
    public void setup() {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        tomcat.enableNaming();
        tomcat.addWebapp("/app", new File("src/test/webapp").getAbsolutePath());
        tomcat.start();
    }

    @Test
    public void testAPI() {
        mockStatic(ExternalAPI.class);
        when(ExternalAPI.getData()).thenReturn(new Data());

        //call Tomcat triggering the call to ExternalAPI.getData()
    }
}

With this configuration I get the following exception:

java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
    at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:849)
    at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:201)
    at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1060)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1783)
...

Now I thought that maybe I need to tell PowerMock to ignore the org.apache.* packages, but then I get this exception:

java.lang.ClassCastException: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
    at javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:190)
    ... 54 more

I have also tried ignoring all org.* packages, which works, but then the ExternalAPI.getData() method is not mocked at all. I suppose this happens because nothing from the Tomcat instance is mocked in this case, since we are ignoring those org.apache.* packages.

Why do I get those exceptions and how should I configure PowerMock?

Aucun commentaire:

Enregistrer un commentaire