从测试类以外的类执行存根时,发生UnfinishedStubbingException

时间:2019-10-24 11:24:48

标签: java unit-testing powermock powermockito

我正在使用PowerMock模拟java.net.Inet4Address(除其他事项外)以返回特定IP地址(getHostAddress())以及是否回送(isLoopbackAddress()) 。我发现,如果我在测试类或直接内部类之外的任何地方执行实际的存根(PowerMock.doReturn(...).when(mock).methodToStub()),则会收到UnfinishedStubbingException。

如果我尝试执行两个存根,则问题最明显。第一个没有异常通过,但是第二个抛出异常,因为它认为第一个未完成。如果我只执行一个存根,那么根据执行此操作后,我会看到不同的错误,因此,这肯定是导致问题的第一个存根。

下面是一些说明问题的代码。

TestClass.java

/* package, imports... */

@RunWith(PowerMockRunner.class)
@PrepareForTest({Inet4Address.class})
public class TestClass {

    @Test
    public void test() {
        Inet4Address mocked = PowerMockito.mock(Inet4Address.class);

        // Option 1: Do it from within this class - WORKS
        doStubbing(mocked);

        // Option 2: Do it from an inner class - WORKS
        Inner.doStubbing(mocked);

        // Option 3: Do it from an inner class of the inner class - FAILS
        Inner.Deeper.doStubbing(mocked);

        // Option 4: Do it from an entirely different class - FAILS
        OtherClass.doStubbing(mocked);
    }

    private void doStubbing(Inet4Address mocked) {
        PowerMockito.doReturn(true).when(mocked).isLoopbackAddress();
        PowerMockito.doReturn("127.0.0.1").when(mocked).getHostAddress();
    }

    public static class Inner {

        static void doStubbing(Inet4Address mocked) {
            PowerMockito.doReturn(true).when(mocked).isLoopbackAddress();
            PowerMockito.doReturn("127.0.0.1").when(mocked).getHostAddress();
        }

        public static class Deeper {

            static void doStubbing(Inet4Address mocked) {
                PowerMockito.doReturn(true).when(mocked).isLoopbackAddress();
                PowerMockito.doReturn("127.0.0.1").when(mocked).getHostAddress();
            }

        }

    }

}

OtherClass.java

/* package, imports... */

public class OtherClass {

    public static void doStubbing(Inet4Address mocked) {
        PowerMockito.doReturn(true).when(mocked).isLoopbackAddress();
        PowerMockito.doReturn("127.0.0.1").when(mocked).getHostAddress();
    }

}

我已将模拟的创建放在所有场景共同的开始。如果模拟是在进行存根的同一类中创建的,则没有任何区别。为了便于阅读,我还将这些方法设为静态。如果首先实例化类,则行为是相同的。

我知道有解决方法,所以我可以进行测试(在测试类中进行模拟,模拟InetAddress接口而不是IPv4实现,等等),但是我想知道为什么< / em> PowerMock以这种方式运行。如果它只能在测试类中运行,我几乎可以理解它们,但是为什么它也可以在内部类中运行呢?

0 个答案:

没有答案