Power Mockito在方法为私有时抛出“未完成的存根”错误,但在方法受到保护时不会出错

时间:2017-02-07 00:27:03

标签: java mockito private powermock powermockito

我正在尝试使用正确的参数测试方法'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));
    }

}

1 个答案:

答案 0 :(得分:1)

真正的答案是:您通过将该类的基本元素放入私有方法来创建难以测试的代码。

换句话说:如果那件事对你的生产代码如此重要,那么更好的答案就是将底层功能放在自己的类中。所以,你创建了一些界面:

public interface SillyService {
  public String getSillyString();
}

然后使用依赖注入为需要此服务的类提供“某种”实现。

模拟私有方法的愿望始终是糟糕设计决定的结果。因此,答案不在于Mockito或PowerMock,而是通过退回并改进该设计。

对于初学者,可以观看这些videos来学习如何编写可测试的代码。

除此之外:请注意 PowerMock 会影响您可以使用Mockito执行的操作 - 因为PowerMock附带了很多后级版本的Mockito。我的个人建议:摆脱对PowerMock的需求;而只是使用最新/最好的Mockito版本。