InetAddress静态方法不会使用PowerMockito进行模拟

时间:2014-12-08 20:02:51

标签: junit mockito powermock

我在尝试在InetAddress中模拟静态方法时遇到了奇怪的问题。我成功地能够为许多其他类模拟静态方法,并且一切正常,但InetAddress显示不同的行为。我正在使用JUnit 4.x,Mockito 1.9.5& PowerMock 1.5.6。

使用Mockito和PowerMock进行以下测试,InetAddress模拟工作正常 -

@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();
    }
}

当我将下面给出的方法放在某个实用程序中时,InetAddress.getLocalHost()不再模拟并且测试失败。

将其移至实用程序:

private static String getCurrentHost() throws UnknownHostException {
    return InetAddress.getLocalHost().getHostAddress();
}

现在我的测试看起来像(并且失败):

@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());
    }
}

以下是我的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

2 个答案:

答案 0 :(得分:3)

我知道这篇文章很老了,但我找到了解决办法。

而不是@PrepareForTest({ InetAddress.class }),你必须@PrepareForTest({ YouClassThatWrap.class })

在这里(https://code.google.com/p/powermock/wiki/MockSystem),它展示了如何模拟SystemClass。

代码@PrepareForTest({ InetAddress.class })不起作用,因为Powermock无法更改System类代码,因此您需要模拟“wrapper”类。

答案 1 :(得分:0)

我找到了解决方案。 将@PrepareForTest({InetAddress.class})更改为@PrepareForTest({Utility .class, InetAddress.class})