org.mockito.exceptions.misusing.UnfinishedStubbingException 未完成的存根检测到

3

我写了以下代码:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Integer.class)
public class TestClass{


    @Test
        public void test(){
            PowerMockito.mockStatic(Integer.class);
            when(Integer.parseInt(anyString())).thenReturn(0);
            System.out.println(Integer.parseInt("12"));
        }
}

我收到了以下错误信息:
org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at com.ctc.dime.services.autopublisher.stores.StoresPublishingServiceTest.test(StoresPublishingServiceTest.java:120)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!

    at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:291)
    at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:193)
    at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
    at org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
b.....

我做错了什么?
2个回答

3
你应该准备使用系统类的类,而不是系统类本身。请参见https://code.google.com/p/powermock/wiki/MockSystem

编辑

请参见Powermock FAQ

我无法模拟java.lang、java.net、java.io或其他系统类中的类,为什么?

这是因为它们由Java的引导类加载器加载,无法被PowerMock的类加载器进行字节码操作。自PowerMock 1.2.5以来,有一个解决方法,请查看this简单示例以了解如何完成。

我进行了一个小测试,似乎对于java.lang.String有效,但对于java.lang.Integer却无效,原因不明。请参见下面的类。第一个方法失败了。第二个使用String.format的方法可以工作。对我来说,这似乎是一个Powermock的bug。
第三种方法是我的常规解决方法,以避免静态或系统模拟。我只需创建一个包保护方法,并在我的测试中进行监视。我建议您也这样做。这比涉及Powermock更好。
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest( { Dummy.class } )
public class TestClass{
    @Test
        public void testStaticIntegerMocking(){
            PowerMockito.mockStatic(Integer.class);
            when(Integer.parseInt(anyString())).thenReturn(0);
            System.out.println(Dummy.parseInt("12"));
        }

    @Test
    public void assertThatMockingStringWorks() throws Exception {
            PowerMockito.mockStatic(String.class);
            final String string = "string";
            final String args = "args";
            final String returnValue = "returnValue";

            when(String.format(string, args)).thenReturn(returnValue);

            final Dummy systemClassUser = new Dummy();
            assertEquals(systemClassUser.format(string, args), returnValue);
    }

    @Test
    public void testSpying(){
        Dummy dummy = new Dummy();
        dummy = spy(dummy);
        doReturn( 0 ).when(dummy).parseIntToBeSpyed(anyString());
        System.out.println(dummy.parseIntToBeSpyed("12"));
    }
}

虚拟类:
import java.io.IOException;

public class Dummy {
    public static Integer parseInt( String string ) {
        return Integer.parseInt(string);
    }

    public String format(String one, String args) throws IOException {
        return String.format(one, args);
    }

    public Integer parseIntToBeSpyed( String string ) {
        return Integer.parseInt(string);
    }
}

我用 @PrepareForTest(Integer.class) 重写了以下代码行,并且看到旧错误: - gstackoverflow
嗯。"@PrepareForTest(Integer.class) with @PrepareForTest(Integer.class)" 这一定是个打字错误。你想告诉我什么? - Gábor Lipták
使用 @PrepareForTest(Integer.class) 和 **@PrepareForTest(TestClass.class)**。 - gstackoverflow
jrh...@gmail.com的评论,2010年12月2日
我为什么无法模拟java.lang、java.net、java.io或其他系统类中的类?
这是过时了吗?我已经成功地模拟了java.net.URI和java.net.URL对象。
- gstackoverflow
就像我说的那样。它似乎适用于字符串而不适用于整数。这可能是Powermock中的一个错误。 - Gábor Lipták

0

看起来这个方法可能已经被模拟了。

在我这里,注释掉“Integer.parseInt”方法截获行已经很好用了:

@RunWith(PowerMockRunner.class)
@PrepareForTest( { Integer.class } )
public class TestClass{
    @Test
        public void testStaticIntegerMocking() {
            PowerMockito.mockStatic(Integer.class);
        //    when(Integer.parseInt(anyString())).thenReturn(new Integer(10023));
            System.out.println("Hello..."+Integer.parseInt("12"));
        }

    @Test
    public void testStaticIntegerMocking2() {
        PowerMockito.mockStatic(Integer.class);
        when(Integer.decode(anyString())).thenReturn(new Integer(10023));
        System.out.println("HelloX..."+Integer.decode("#ffff"));
    }
}

看起来在这种情况下,“0”是默认的模拟结果。 请注意:如果您返回一个“new Integer(...)”,则测试将不会出错,但仍将返回“0”,即使我们指定了不同的值,例如新的Integer(“1002”)。

等等,还有更多!使用静态方法“Integer.decode(String)”的类似测试运行良好,完全符合预期!请参见上面的第二种方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接