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



我在尝试模拟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());
    }
}

下面给出的是我的堆栈跟踪 -

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
我知道

这篇文章有点旧,但我找到了解决方案。

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

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

代码@PrepareForTest({ InetAddress.class })将不起作用,因为 Powermock 无法更改系统类代码,因此您需要模拟"包装器"类。

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

相关内容

  • 没有找到相关文章

最新更新