Reputation: 152
I am running into weird problem while trying to mock static methods in InetAddress. I am successfully able to mock static methods for many of other classes and all works fine, but InetAddress showing different behavior. I am using JUnit 4.x, Mockito 1.9.5 & PowerMock 1.5.6.
Given below test using Mockito and PowerMock, and InetAddress mocking works fine -
@RunWith(PowerMockRunner.class)
@PrepareForTest({InetAddress.class})
public class UtilityTest {
@Mock
InetAddress inetAddress;
@Test
public void testGetCurrentHost() throws UnknownHostException {
mockStatic(InetAddress.class);
when(InetAddress.getLocalHost()).thenReturn(inetAddress);
when(inetAddress.getHostAddress()).thenReturn("1.1.1.1");
assertEquals("1.1.1.1", getCurrentHost());
}
private static String getCurrentHost() throws UnknownHostException {
return InetAddress.getLocalHost().getHostAddress();
}
}
When I put the given below method in some utility, InetAddress.getLocalHost() doesn't mock anymore and test fails.
Move it to Utility :
private static String getCurrentHost() throws UnknownHostException {
return InetAddress.getLocalHost().getHostAddress();
}
Now my test looks like (and fails) :
@RunWith(PowerMockRunner.class)
@PrepareForTest({InetAddress.class})
public class UtilityTest {
@Mock
InetAddress inetAddress;
@Test
public void testGetCurrentHost() throws UnknownHostException {
mockStatic(InetAddress.class);
when(InetAddress.getLocalHost()).thenReturn(inetAddress);
when(inetAddress.getHostAddress()).thenReturn("1.1.1.1");
assertEquals("1.1.1.1", Utility.getCurrentHost());
}
}
Given below is my stacktrace -
org.junit.ComparisonFailure:
Expected :1.1.1.1
Actual :192.111.111.121
<Click to see difference>
at org.junit.Assert.assertEquals(Assert.java:115)
at org.junit.Assert.assertEquals(Assert.java:144)
at com.somecompany.helper.INetTest.testGetCurrentHost(INetTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Process finished with exit code -1
Upvotes: 5
Views: 7617
Reputation: 1
I found a solution.
change @PrepareForTest({InetAddress.class})
to @PrepareForTest({Utility .class, InetAddress.class})
Upvotes: 0
Reputation: 1912
I know that this post is kind old, but I found a solution.
Instead doing @PrepareForTest({ InetAddress.class })
, you must do @PrepareForTest({ YouClassThatWrap.class })
.
In here (https://code.google.com/p/powermock/wiki/MockSystem) it shows how to mock a SystemClass.
The code @PrepareForTest({ InetAddress.class })
will not work because Powermock cannot change a System class code, so you need to mock the "wrapper" class.
Upvotes: 3