org.mockito.exceptions.misusing.UnfinishedStubbingException Unfinished stubbing detected

£可爱£侵袭症+ 提交于 2019-12-06 07:04:28

You should prepare the class that uses the system class, and not the system class itself. See https://code.google.com/p/powermock/wiki/MockSystem

EDIT

See the Powermock FAQ:

I cannot mock classes in from java.lang, java.net, java.io or other system classes, why?

This is because they're loaded by Java's bootstrap classloader and cannot be byte-code manipulated by PowerMock's classloader. Since PowerMock 1.2.5 there's a work-around, please have a look at this simple example to see how it's done.

I made a small test, and it seems to be working for java.lang.String but not for java.lang.Integer for whatever reason. See the classes below. The first method fails. The second with String.format works. This seems to be a Powermock bug for me.

The third method is my usual workaround to avoid static or system mocking. I just create a package protected method, and I spy it in my test. I recommend the same. It is better than involving 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"));
    }
}

The Dummy class:

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

It seems the method might already have been mocked.

Commenting out the "Integer.parseInt" method interception line has worked fine for me:

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

It seems "0" is the default mock result in such a case. Please notice: if you return a "new Integer(...)" the test will execute with no errors, but still "0" will be returned, even if we specify a different value, as e.g. new Integer("1002").

But wait, there's more! A similar test worked fine, exactly as it would expected, with static method "Integer.decode(String)"! See the second method above.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!