我正在尝试使用正确的参数测试方法'reallyCoolMethod'。问题是存在“getSillyString”方法导致错误。当'getSillyString'方法是私有的时,测试将在第二个doReturn上失败:
doReturn("superSilly").when(spy, "getSillyString", 5, false);
但是当方法受到保护时,测试将通过。错误是:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:36)
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!
以下是受测试的课程:
import java.util.Random;
@Singleton
public class FooBar {
@Inject
public FooBar(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
@POST
@Path("foos/")
public fooAction createFoo() {
word1 = getSillyString(4, true);
word2 = getSillyString(5, false);
int id = reallyCoolMethod(word1,word2);
}
private String getSillyString(int size, boolean allCaps){
}
}
以下是测试:
import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.mockito.Mockito;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.spy;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
public class FooTest {
@Test
public void testCreateFoo() throws Exception {
Foo foo = Mockito.mock(Foo.class);
Bar bar = Mockito.mock(Bar.class);
FooBar resource = new FooBar(foo, bar);
FooBar spy = spy(resource);
doReturn("reallySilly").when(spy, "getSillyString", 4, true);
doReturn("superSilly").when(spy, "getSillyString", 5, false);
doReturn(1).when(spy).reallyCoolMethod(Mockito.anyString(),Mockito.anyString());
spy.createFoo();
verify(spy).reallyCoolMethod(Mockito.eq("reallySilly"),Mockito.Eq(superSilly));
}
}
答案 0 :(得分:1)
真正的答案是:您通过将该类的基本元素放入私有方法来创建难以测试的代码。
换句话说:如果那件事对你的生产代码如此重要,那么更好的答案就是将底层功能放在自己的类中。所以,你创建了一些界面:
public interface SillyService {
public String getSillyString();
}
然后使用依赖注入为需要此服务的类提供“某种”实现。
模拟私有方法的愿望始终是糟糕设计决定的结果。因此,答案不在于Mockito或PowerMock,而是通过退回并改进该设计。
对于初学者,可以观看这些videos来学习如何编写可测试的代码。
除此之外:请注意 PowerMock 会影响您可以使用Mockito执行的操作 - 因为PowerMock附带了很多后级版本的Mockito。我的个人建议:摆脱对PowerMock的需求;而只是使用最新/最好的Mockito版本。