Java Mockito-网络方法内的试验方法

Java Mockito-网络方法内的试验方法,java,unit-testing,junit,mockito,powermockito,Java,Unit Testing,Junit,Mockito,Powermockito,我正在测试我的Utils类。有些方法使用其他类方法。我想模拟使用的内部方法,以便测试将假定它们工作(为了使它成为真正的单元测试,测试特定方法) 我想测试“buildUrl”方法: public static String buildUrl(String path, List<Pair> queryParams, DateFormat dateFormat) { final StringBuilder url = new StringBuilder(); url.ap

我正在测试我的Utils类。有些方法使用其他类方法。我想模拟使用的内部方法,以便测试将假定它们工作(为了使它成为真正的单元测试,测试特定方法)

我想测试“buildUrl”方法:

 public static String buildUrl(String path, List<Pair> queryParams, DateFormat dateFormat) {
    final StringBuilder url = new StringBuilder();
    url.append(path);

    if (queryParams != null && !queryParams.isEmpty()) {
        // support (constant) query string in `path`, e.g. "/posts?draft=1"
        String prefix = path.contains("?") ? "&" : "?";
        for (Pair param : queryParams) {
            if (param.getValue() != null) {
                if (prefix != null) {
                    url.append(prefix);
                    prefix = null;
                } else {
                    url.append("&");
                }
                String value = Utils.parameterToString(param.getValue(), dateFormat);
                url.append(Utils.escapeString(param.getName())).append("=").append(Utils.escapeString(value));
            }
        }
    }

    return url.toString();
}
publicstaticstringbuildurl(字符串路径、列表查询参数、DateFormat-DateFormat){
最终StringBuilder url=新StringBuilder();
append(路径);
if(queryParams!=null&&!queryParams.isEmpty()){
//“路径”中支持(常量)查询字符串,例如“/posts?draft=1”
字符串前缀=路径。包含(“?”?&“:”;
for(配对参数:queryParams){
if(param.getValue()!=null){
if(前缀!=null){
url.append(前缀);
前缀=空;
}否则{
url.append(“&”);
}
字符串值=Utils.parameterToString(param.getValue(),dateFormat);
append(Utils.escapeString(param.getName()).append(“=”).append(Utils.escapeString(value));
}
}
}
返回url.toString();
}
BuildUrl使用“parameterToString”(和其他),我想在测试中模拟它。所以我试过这样的方法:

 @Test
public void testBuildUrl(){
    Utils util = new Utils();
    Utils utilSpy = Mockito.spy(util);
    Mockito.when(utilSpy.parameterToString("value1",new RFC3339DateFormat())).thenReturn("value1");
    List<Pair> queryParams = new ArrayList<Pair>();
    queryParams.add(new Pair("key1","value1"));
    String myUrl = utilSpy.buildUrl("this/is/my/path", queryParams, new RFC3339DateFormat());
    assertEquals("this/is/my/path?key1=value1&key2=value2", myUrl);
}
@测试
公共void testBuildUrl(){
Utils util=新Utils();
Utils utilSpy=Mockito.spy(util);
Mockito.when(utilSpy.parameterToString(“value1”,新的RFC3339DateFormat())。然后返回(“value1”);
List queryParams=new ArrayList();
添加(新对(“键1”、“值1”);
字符串myUrl=utilSpy.buildUrl(“this/is/my/path”,queryParams,新的RFC3339DateFormat());
assertEquals(“this/is/my/path?key1=value1&key2=value2”,myUrl);
}
但是我从Mockito那里得到了
MissingMethodInvocationException

所以我的问题实际上是-如何模拟已在测试方法中调用的方法,以及我的测试有什么问题。谢谢。

您不能使用标准Mockito模拟/监视静态调用

您必须使用Powermockito和其他工具来执行以下操作:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Utils.class)    
public class MyClassTest{

    @Test
    public void testBuildUrl(){
         PowerMockito.mockStatic(Utils.class);

         // mock the static method to return certain values
         Mockito.when(Utils.parameterToString("value1",new RFC3339DateFormat()))
             .thenReturn("value1");
         Mockito.when(Utils.escapeString(anyString()).thenReturn(desiredResult);

       // rest of test code
    }

下面是一些需要通读的内容->

您不能使用标准Mockito模拟/监视静态调用

您必须使用Powermockito和其他工具来执行以下操作:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Utils.class)    
public class MyClassTest{

    @Test
    public void testBuildUrl(){
         PowerMockito.mockStatic(Utils.class);

         // mock the static method to return certain values
         Mockito.when(Utils.parameterToString("value1",new RFC3339DateFormat()))
             .thenReturn("value1");
         Mockito.when(Utils.escapeString(anyString()).thenReturn(desiredResult);

       // rest of test code
    }
这里还有一些内容需要通读->

我想模拟使用的内部方法,以便测试将假定它们工作(为了使它成为真正的单元测试,测试特定方法)

单元测试不测试特定方法

UnitTests测试被测代码的公共可观察行为


如果您觉得应该嘲笑某些方法,这可能是您的设计需要改进的迹象。没有必要使实用方法
静态
,而且您的测试类可能需要承担很多责任

当然,PowerMock将克服测试中的问题,但我认为使用PowerMock是对糟糕设计的屈服

我想模拟使用的内部方法,以便测试将假定它们工作(为了使它成为真正的单元测试,测试特定方法)

单元测试不测试特定方法

UnitTests测试被测代码的公共可观察行为


如果您觉得应该嘲笑某些方法,这可能是您的设计需要改进的迹象。没有必要使实用方法
静态
,而且您的测试类可能需要承担很多责任

当然,PowerMock将克服测试中的问题,但我认为使用PowerMock是对糟糕设计的屈服