我有以下类,其中包含一个永远不会更改的硬编码 URL:
public class HttpClient {
private final String DOWNLOAD_URL = "http://original.url.json";
public String readJsonDataFromUrl() throws IOException {
URLConnection urlConnection = getUrlConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer content = new StringBuffer();
String readLine = "";
while ((readLine = reader.readLine()) != null) {
content.append(readLine);
}
return content.toString();
}
private URLConnection getUrlConnection() throws IOException {
URL jsonLocator = new URL(DOWNLOAD_URL);
return jsonLocator.openConnection();
}
}
现在想象一下,我希望在我的测试中出现 IOException。在我看来,这样做的唯一方法是在模拟对象中重写完整的类,因为 final 变量:
public class HttpClientMock extends HttpClient {
private final String DOWNLOAD_URL = "http://wrong.test.url.json";
@Override
public String readJsonDataFromUrl() throws IOException {
URLConnection urlConnection = getUrlConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer content = new StringBuffer();
String readLine = "";
while ((readLine = reader.readLine()) != null) {
content.append(readLine);
}
return content.toString();
}
private URLConnection getUrlConnection() throws IOException {
URL jsonLocator = new URL(DOWNLOAD_URL);
URLConnection urlConnection = jsonLocator.openConnection();
return urlConnection;
}
}
但这有点牵强。如果更改原始方法,测试结果可能仍然是肯定的,因为通过此尝试,我实际上不再测试原始类。
如何正确地做到这一点?(我不想只为这个测试使用一个框架,那么有没有设计尝试以一种通用的方式解决这个问题?)