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)
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...
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With