【问题标题】:InetAddress static method doesn't mock with PowerMockitoInetAddress 静态方法不使用 PowerMockito 模拟
【发布时间】:2014-12-08 20:02:50
【问题描述】:

我在尝试模拟 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

【问题讨论】:

  • 发布您的堆栈跟踪
  • 嘿 Ankit,我刚刚在问题的底部添加了堆栈跟踪。非常感谢您花时间研究这个!!!
  • 因此,一旦您将方法放入某个实用程序类中,您就不再使用您的模拟对象,在您的情况下是 InetAddress inetAddress;您的实用程序类不会使用。这不再是单元测试了
  • Ankit,我这样放代码是为了看起来简单。实际上我正在为类实用程序编写单元测试。如果没有意义,请告诉我。此外,我以与我的实用程序类调用/使用的静态方法相同的方式模拟了静态方法,并且模拟得很好。

标签: junit mockito powermock


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多