无法阅读 Mocked Java.io.Reader
Can't read Mocked Java.io.Reader
我想用 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()
方法不是 returning 1。相反,它总是 returns -1。我应该如何模拟 Reader
以便 read()
方法将 return 除了 -1.
之外的其他东西
谢谢。
一定有用,抱歉让你有点困惑)
// annotations is very important, cls I your tested class name, i assume cls is yours
@RunWith(PowerMockRunner.class)
@PrepareForTest({cls.class})
public class PrinterTest {
@Test
public void print() throws Exception {
String url = "";
GetMethod method = Mockito.mock(GetMethod.class);
InputStream inputStream = Mockito.mock(InputStream.class);
InputStreamReader reader = Mockito.mock(InputStreamReader.class);
Mockito.when(method.getResponseBodyAsStream()).thenReturn(inputStream);
//forgot about it )
PowerMockito.whenNew(GetMethod.class).withArguments(eq(url)).thenReturn(method);
PowerMockito.whenNew(InputStreamReader.class).withArguments(eq(inputStream)).thenReturn(reader);
Mockito.when(reader.read()).thenReturn((int) '1', -1);
when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
String actualResult = cls.funcToTest(url);
String expected = "1";
assertEquals(expected, actualResult);
}
}
首先,您的测试代码进行了大量 .class
模拟以模拟函数局部变量/引用。模拟是针对 class 依赖项而不是函数局部变量。
正如所写,您无法单独使用模拟来测试您的函数 funcToTest
。如果您不愿意将真实对象用于 - HttpMethod
& Reader
,则需要重写此函数。
如果您希望模拟对这些对象的调用并用此 get 方法替换 new
的代码,则需要删除此函数之外的带有 new
的对象创建代码。例如
protected HttpMethod getHttpMethod(String Url){
return new GetMethod(url);
}
另外,我没有看到你嘲笑这一行是假的 URL - 这似乎是单元测试所必需的。
String url = Config.getURL(serviceName);
在你的函数之外获取对象创建代码后,你需要创建一个新的 class 而不是扩展你的 SUT
(被测对象)并覆盖这些方法(getHttpMethod
)提供 fake/mocked 个实例。
您需要编写类似的方法来获取 Reader
个实例。
然后测试这个新的 class - 从 SUT 扩展而来,因为对象创建逻辑不需要测试。
如果不将对象创建代码放在函数之外,我看不到通过 mockito 模拟它的方法。
希望对您有所帮助!!
我想用 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()
方法不是 returning 1。相反,它总是 returns -1。我应该如何模拟 Reader
以便 read()
方法将 return 除了 -1.
谢谢。
一定有用,抱歉让你有点困惑)
// annotations is very important, cls I your tested class name, i assume cls is yours
@RunWith(PowerMockRunner.class)
@PrepareForTest({cls.class})
public class PrinterTest {
@Test
public void print() throws Exception {
String url = "";
GetMethod method = Mockito.mock(GetMethod.class);
InputStream inputStream = Mockito.mock(InputStream.class);
InputStreamReader reader = Mockito.mock(InputStreamReader.class);
Mockito.when(method.getResponseBodyAsStream()).thenReturn(inputStream);
//forgot about it )
PowerMockito.whenNew(GetMethod.class).withArguments(eq(url)).thenReturn(method);
PowerMockito.whenNew(InputStreamReader.class).withArguments(eq(inputStream)).thenReturn(reader);
Mockito.when(reader.read()).thenReturn((int) '1', -1);
when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
String actualResult = cls.funcToTest(url);
String expected = "1";
assertEquals(expected, actualResult);
}
}
首先,您的测试代码进行了大量 .class
模拟以模拟函数局部变量/引用。模拟是针对 class 依赖项而不是函数局部变量。
正如所写,您无法单独使用模拟来测试您的函数 funcToTest
。如果您不愿意将真实对象用于 - HttpMethod
& Reader
,则需要重写此函数。
如果您希望模拟对这些对象的调用并用此 get 方法替换 new
的代码,则需要删除此函数之外的带有 new
的对象创建代码。例如
protected HttpMethod getHttpMethod(String Url){
return new GetMethod(url);
}
另外,我没有看到你嘲笑这一行是假的 URL - 这似乎是单元测试所必需的。
String url = Config.getURL(serviceName);
在你的函数之外获取对象创建代码后,你需要创建一个新的 class 而不是扩展你的 SUT
(被测对象)并覆盖这些方法(getHttpMethod
)提供 fake/mocked 个实例。
您需要编写类似的方法来获取 Reader
个实例。
然后测试这个新的 class - 从 SUT 扩展而来,因为对象创建逻辑不需要测试。
如果不将对象创建代码放在函数之外,我看不到通过 mockito 模拟它的方法。
希望对您有所帮助!!