Junit Can';t读取模拟Java.io.Reader

Junit Can';t读取模拟Java.io.Reader,junit,mockito,java-io,Junit,Mockito,Java Io,我想用Mockito测试以下代码: public static String funcToTest(String query) throws Exception { String url = Config.getURL(serviceName); HttpClient client = new HttpClient(); HttpMethod method = new GetMethod(url); String resultantString= "";

我想用Mockito测试以下代码:

public static String funcToTest(String query) throws Exception {
    String url = Config.getURL(serviceName);
    HttpClient client = new HttpClient();
    HttpMethod method = new GetMethod(url);
    String resultantString= "";

    method.setQueryString(URIUtil.encodeQuery(query));
    client.executeMethod(method);
    if (method.getStatusCode() == HttpStatus.SC_OK) {
        Reader reader = new InputStreamReader(method
                    .getResponseBodyAsStream());
        int charValue = 0;
        StringBuffer sb = new StringBuffer(1024);
        while ((charValue = reader.read()) != -1) {
            sb.append((char) charValue);
        }
        resultantString = sb.toString();
    }
    method.releaseConnection();
    return resultantString;
}
我创建了如下测试:

@Test
public void testFunc() throws Exception{
    HttpMethod method =  Mockito.mock(HttpMethod.class);
    InputStream inputStream = Mockito.mock(InputStream.class);
    Reader reader = Mockito.mock(Reader.class);

    when(method.getResponseBodyAsStream()).thenReturn(inputStream);
    PowerMockito.whenNew(Reader.class).withArguments(eq(inputStream)).thenReturn(reader);

    Mockito.when(reader.read()).thenReturn((int)'1', -1);


    String actualResult = cls.funcToTest("");
    String expected = "1";
    assertEquals(expected, actualResult);
}
但是
reader.read()
方法没有返回1。相反,它总是返回-1。我应该如何模拟
Reader
,以便
read()
方法将返回除-1之外的其他内容


谢谢

一定行得通,很抱歉是什么让你有点困惑)


首先,您的测试代码正在对模拟函数局部变量/引用进行大量的
.class
模拟。模拟用于类依赖项,而不是函数局部变量

如前所述,您不能仅通过模拟来测试函数
funcToTest
。如果不愿意将真实对象用于-
HttpMethod
&
Reader
,则需要重写此函数

如果您希望模拟对这些对象的调用,并使用此get方法替换
new
的代码,则需要在该函数之外删除带有
new
的对象创建代码。e、 g

protected HttpMethod getHttpMethod(String Url){
   return new GetMethod(url);
}
另外,我没有看到你为了一个虚假的URL而嘲笑这一行——这似乎是单元测试所必需的

String url = Config.getURL(serviceName);
在将对象创建代码置于函数之外之后,您需要创建一个新类来扩展
SUT
(测试主题),并重写这些方法(
getHttpMethod
)以提供假/模拟实例

您需要编写类似的方法来获取
Reader
实例

然后测试这个新类-从SUT扩展而来,因为不需要测试对象创建逻辑

如果不将对象创建代码带到函数之外,我看不到mockito对其进行模拟的方法


希望能有帮助

System.out.println(inputStream.read())
打印1,但
resultrader.read()
方法内部每次循环返回-1。所以它
sb
总是空的。请更新你的帖子并给出整个测试类,现在它真的很模糊。但您的输出是-1,因为您不在real方法中传递模拟对象,而是创建其他输入流。尝试PowerMockito.whenNew(InputStreamReader.class)。使用参数(eq(expectedArg1)、eq(expectedArg2),…)。然后返回(expectedReader);它将帮助您注入mockI已经尝试过的
PowerMockito.whenNew(InputStreamReader.class).withArguments(inputStream).thenReturn(reader),但这里我们在InputStreamReader类上做了新的操作,并获取Reader对象。因此,它给出了一个不匹配参数的错误。注意。我更新了问题。你忘了eq()数学,再试一次eq(inputStream)@Emi我编辑了我的答案。现在再试一次,我想它会有用的@PrepareForTest({cls.class})
String url = Config.getURL(serviceName);