"XmlPullParserFactory not mocked" issue while unit testing
Asked Answered
B

3

5

I am doing a unit testing which includes parsing of data with XStream parser.I used Mockito for mocking context.But the test case fails with an error log:

java.lang.RuntimeException: Method newInstance in org.xmlpull.v1.XmlPullParserFactory not mocked. See http://g.co/androidstudio/not-mocked for details.

at org.xmlpull.v1.XmlPullParserFactory.newInstance(XmlPullParserFactory.java)
at com.thoughtworks.xstream.io.xml.XppDriver.createParser(XppDriver.java:57)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:54)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:65)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1049)
at com.att.apis.metadata.MetadataHandler.execute(MetadataHandler.java:38)
at com.att.apis.services.ServerOperations.executePostOperation(ServerOperations.java:20)
at com.att.framework.helper.request.MetadataAPIHandler.executeAPIRequest(MetadataAPIHandler.java:58)
at com.att.framework.helper.request.MetadataAPIHandlerMokitoTest.executeAPIRequest(MetadataAPIHandlerMokitoTest.java:57)

The error is happening at the line " response = (MetadataResponse)xs.fromXML(iStream); " in the below code block

InputStream iStream = responseData.getInputStream();
        XStream xs = new XStream();
        xs.autodetectAnnotations(true);
        xs.alias("helloa", A.class);
        xs.alias("hellob", B.class);
        xs.alias("helloc",C.class);
        response =  (MetadataResponse)xs.fromXML(iStream);

As per the answer from Android: XmlPullParserFactory.newInstance() creating a null factory, I added

testOptions {
    unitTests.returnDefaultValues = true
}

in build.gradle.

After the update when NullPointer Exception with below log occurred.

java.lang.NullPointerException
at com.thoughtworks.xstream.io.xml.XppDriver.createParser(XppDriver.java:59)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:54)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:65)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1049)
at com.att.apis.metadata.MetadataHandler.execute(MetadataHandler.java:38)
at com.att.apis.services.ServerOperations.executePostOperation(ServerOperations.java:20)
at com.att.framework.helper.request.MetadataAPIHandler.executeAPIRequest(MetadataAPIHandler.java:58)
at com.att.framework.helper.request.MetadataAPIHandlerMokitoTest.executeAPIRequest(MetadataAPIHandlerMokitoTest.java:57)

Can anyone help me to sort out the issue

Barbican answered 6/4, 2017 at 13:40 Comment(0)
W
3

XmlPullParserFactory comes from the Android platform and therefore can not be mocked in the unit tests as they are executed with the Java VM you have installed on your computer.

You may want to use the Robolectric framework, it allows for the unit tests to make calls to the Android platform (it mocks almost everything in the whole platform)

Wacker answered 6/4, 2017 at 13:44 Comment(0)
B
8

If you think that mocking XmlPullParser is not a good idea and you would rather write tests against the real parser, so you can check whether real XML documents are actually parsed correctly by your code, this is how you can solve it:

Simply add this xmlpull dependency to your app's gradle file:

testImplementation group: 'xmlpull', name: 'xmlpull', version: '1.1.3.1' 

It will be used only for running the unit tests and will not be packaged in your APK

Braggart answered 14/12, 2017 at 12:26 Comment(4)
Finally ... a helpful answer!! :)Whirl
testImplementation 'xmlpull:xmlpull:1.1.3.1' is more idiomatic than using group, name, version` labelsYelena
For Android API Level 28, I had to use testImplementation 'net.sf.kxml:kxml2:2.3.0'Yelena
@HeathBorders your suggestion indeed helped. I ran into a different error where after we pulled PayPal SDK the xml specific tests were failing and the suggestion to add testImplementation 'net.sf.kxml:kxml2:2.3.0' was the only thing that resolved the issue.Package
W
3

XmlPullParserFactory comes from the Android platform and therefore can not be mocked in the unit tests as they are executed with the Java VM you have installed on your computer.

You may want to use the Robolectric framework, it allows for the unit tests to make calls to the Android platform (it mocks almost everything in the whole platform)

Wacker answered 6/4, 2017 at 13:44 Comment(0)
A
0

You should refactor your code a bit and mock Xstream and all it's dependencies. For example you can externalize creation of Xstream and pass it to your method under test.

    Xstream mockXstream = Mockito.mock(Xstream.class);
    //mock all xstream method calls

    void myMethodUnderTest(Xstream xs){
            InputStream iStream = responseData.getInputStream();
            xs.autodetectAnnotations(true);
            xs.alias("helloa", A.class);
            xs.alias("hellob", B.class);
            xs.alias("helloc",C.class);
            response =  (MetadataResponse)xs.fromXML(iStream);
    }
Apocopate answered 6/4, 2017 at 13:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.