org.mockito.exceptions.misusing.UnfinishedStubbingException 检测到未完成的存根
org.mockito.exceptions.misusing.UnfinishedStubbingException Unfinished stubbing detected
我写了下面的代码:
@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.....
我做错了什么?
您应该准备使用系统 class 的 class,而不是系统 class 本身。参见 https://code.google.com/p/powermock/wiki/MockSystem
编辑
查看 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.
我做了一个小测试,它似乎对 java.lang.String 有效,但出于某种原因对 java.lang.Integer 无效。请参阅下面的 classes。第一种方法失败。第二个 String.format 有效。这对我来说似乎是一个 Powermock 错误。
第三种方法是我常用的解决方法,可以避免静态或系统模拟。我只是创建了一个包保护方法,并在我的测试中监视它。我推荐相同的。它比涉及 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"));
}
}
假人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);
}
}
似乎该方法可能已经被模拟了。
注释掉 "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”似乎是默认的模拟结果。
请注意:如果你 return a "new Integer(...)" 测试将无错误地执行,但仍然是“0” returned,即使我们指定了不同的值,例如新整数(“1002”)。
等等,还有更多!使用静态方法 "Integer.decode(String)",类似的测试工作正常,完全符合预期!见上面第二种方法。
我写了下面的代码:
@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.....
我做错了什么?
您应该准备使用系统 class 的 class,而不是系统 class 本身。参见 https://code.google.com/p/powermock/wiki/MockSystem
编辑
查看 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.
我做了一个小测试,它似乎对 java.lang.String 有效,但出于某种原因对 java.lang.Integer 无效。请参阅下面的 classes。第一种方法失败。第二个 String.format 有效。这对我来说似乎是一个 Powermock 错误。
第三种方法是我常用的解决方法,可以避免静态或系统模拟。我只是创建了一个包保护方法,并在我的测试中监视它。我推荐相同的。它比涉及 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"));
}
}
假人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);
}
}
似乎该方法可能已经被模拟了。
注释掉 "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”似乎是默认的模拟结果。 请注意:如果你 return a "new Integer(...)" 测试将无错误地执行,但仍然是“0” returned,即使我们指定了不同的值,例如新整数(“1002”)。
等等,还有更多!使用静态方法 "Integer.decode(String)",类似的测试工作正常,完全符合预期!见上面第二种方法。