Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

issue while using powermockito to mock the URL class

Without going into the details of the merit of doing this way, just need help figuring out why the following test codes do not work! This has been more of a learning exercise at this point..

Just trying to use PowerMockito to create a mock for the URL class, and define some behaviors for it. Here's the code:

package com.icidigital.services

import com.icidigital.services.impl.WeatherServiceImpl
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner


/**
 * Created by apil.tamang on 7/27/15.
 * I could not get the setup to finish! Failed!
 */
@PrepareForTest(URL.class)
@RunWith(PowerMockRunner.class)
class WeatherServiceImplTest {


    URL mockURL;
    URLConnection mockConn;

    @Before
    public void setUp(){

        byte[] data = "123,456".getBytes();

        InputStream input = new ByteArrayInputStream(data);

        //define and set behavior for mockConn
        mockConn=PowerMockito.mock(HttpURLConnection.class);
        //Mockito.doCallRealMethod().when(mockConn).getResponseCode();
        //Mockito.when(mockConn.getResponseCode()).thenCallRealMethod().thenReturn(200);
        //Mockito.when(mockConn.getInputStream()).thenReturn(input);

        //define and set behavior for mockURLObj
        mockURL=PowerMockito.mock(URL.class);
        PowerMockito.when(mockURL.openConnection()).thenReturn(mockConn);


    }

    @Test
    public void testSetup(){

        WeatherServiceImpl testObj=new WeatherServiceImpl(mockURL);
        String response=testObj.run("foobar");
        PowerMockito.verifyNew(mockURL);





    }

}

The following exception stack is thrown. In particular, linke 39 of this test, which is where I have: PowerMockito.when(mockURL.openConnection()).thenReturn(mockConn); throws the error. Mind you that URL is a final class, and that's I'm using Powermockito.

java.lang.AbstractMethodError
    at java.net.URL.openConnection(URL.java:971)
    at java_net_URL$openConnection.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at com.icidigital.services.WeatherServiceImplTest.setUp(WeatherServiceImplTest.groovy:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:129)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:93)
like image 254
apil.tamang Avatar asked Jul 29 '15 13:07

apil.tamang


3 Answers

Well this isn't exactly a solution, and I've simply graduated a different error now, but at least the annoying 'AbstractMethodError' is now gone.

What I did was to add the following classes for the prepareClassForTest annotation:

....
@PrepareForTest({URL.class, URLConnection.class, WeatherServiceImplTest.class} )
...

Was mildly suspicious, but the following post kind of affirmed that doubt: powermock puzzler

Anyways, wish me luck guys. Second day of mocking my way around, and I'm all mucked up and ready to drop the ball...

like image 164
apil.tamang Avatar answered Nov 20 '22 17:11

apil.tamang


I am not really sure, but try to use Mockito for mocking the method call. It seems I have already had such problem, and I think there is some bug from PowerMockito side.

As I remember if you will use

Mockito.when(mockURL.openConnection()).thenReturn(mockConn);

instead of

PowerMockito.when(mockURL.openConnection()).thenReturn(mockConn);

it will work normally.

Or If it is wrong try to use alternative way such as

Mockito/PowerMockito.doReturn(mockConn).when(mockUrl).openConnection();

And if some of these will work, it seems the reason is unhandled situation by PowerMockito dev team. And power mockito invoke real method as well as or instead of mocked method.

like image 29
Eugene Stepanenkov Avatar answered Nov 20 '22 18:11

Eugene Stepanenkov


URL is final class. To mock final class we can use PowerMockito with Junit. To mock final class we need to annotate Test class with @RunWith(PowerMockRunner.class) and @PrepareForTest({ URL.class })


@RunWith(PowerMockRunner.class) 
@PrepareForTest({ URL.class })
public class Test {
    @Test
    public void test() throws Exception {
        URL url = PowerMockito.mock(URL.class);
        HttpURLConnection huc = Mockito.mock(HttpURLConnection.class);
        PowerMockito.when(url.openConnection()).thenReturn(huc);
        assertTrue(url.openConnection() instanceof HttpURLConnection);
    }
}

But in the line PowerMockito.when(url.openConnection()).thenReturn(huc); following error is thrown:

java.lang.AbstractMethodError
    at java.net.URL.openConnection(URL.java:971)
    at java_net_URL$openConnection.call(Unknown Source) 

In order to get rid of this error we can modify our Test class as shown below:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ URL.class })
public class Test {
    @Test
    public void test() throws Exception {

        public class UrlWrapper {

            URL url;

            public UrlWrapper(String spec) throws MalformedURLException {
                url = new URL(spec);
            }

            public URLConnection openConnection() throws IOException {
                return url.openConnection();
            }
        }

        UrlWrapper url = Mockito.mock(UrlWrapper.class);
        HttpURLConnection huc = Mockito.mock(HttpURLConnection.class);
        PowerMockito.when(url.openConnection()).thenReturn(huc);
        assertTrue(url.openConnection() instanceof HttpURLConnection);
    }
}

Visit: https://programmingproblemsandsolutions.blogspot.com/2019/04/abstractmethoderror-is-thrown-on.html

like image 1
Pranab Thakuria Avatar answered Nov 20 '22 18:11

Pranab Thakuria