Kyl*_*ine 6 java junit unit-testing http mockito
我正在尝试为我的程序编写单元测试并使用模拟数据。我对如何拦截对 URL 的 HTTP Get 请求有点困惑。
我的程序调用 API 的 URL,并返回一个简单的 XML 文件。我希望测试不是从在线 API 获取 XML 文件,而是从我这里接收预定的 XML 文件,以便我可以将输出与预期输出进行比较,并确定一切是否正常工作。
有人向我指出了 Mockito,并且看到了许多不同的示例,例如这篇 SO 帖子,如何使用 Mockito 来测试 REST 服务?但我并不清楚如何设置这一切以及如何模拟数据(即,每当调用 URL 时都返回我自己的 xml 文件)。
我唯一能想到的是制作另一个在 Tomcat 上本地运行的程序,并在我的测试中传递一个特殊的 URL,该 URL 调用 Tomcat 上本地运行的程序,然后返回我想要测试的 xml 文件。但这似乎有点矫枉过正,我认为这是不可接受的。有人可以指出我正确的方向吗?
private static InputStream getContent(String uri) {
HttpURLConnection connection = null;
try {
URL url = new URL(uri);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
return connection.getInputStream();
} catch (MalformedURLException e) {
LOGGER.error("internal error", e);
} catch (IOException e) {
LOGGER.error("internal error", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Spring Boot 和 Spring 框架的其他部分(如果有帮助的话)。
部分问题在于您没有将事物分解为接口。您需要包装getContent到一个接口中并提供一个实现该接口的具体类。然后需要将此具体类传递到任何使用原始getContent. (这本质上是依赖倒置。)您的代码最终将看起来像这样。
public interface IUrlStreamSource {
InputStream getContent(String uri)
}
public class SimpleUrlStreamSource implements IUrlStreamSource {
protected final Logger LOGGER;
public SimpleUrlStreamSource(Logger LOGGER) {
this.LOGGER = LOGGER;
}
// pulled out to allow test classes to provide
// a version that returns mock objects
protected URL stringToUrl(String uri) throws MalformedURLException {
return new URL(uri);
}
public InputStream getContent(String uri) {
HttpURLConnection connection = null;
try {
Url url = stringToUrl(uri);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
return connection.getInputStream();
} catch (MalformedURLException e) {
LOGGER.error("internal error", e);
} catch (IOException e) {
LOGGER.error("internal error", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用静态的代码getContent应该通过IUrlStreamSource实例getContent()。然后,您向要测试的对象提供模拟IUrlStreamSource而不是SimpleUrlStreamSource.
如果您想测试SimpleUrlStreamSource(但没有太多需要测试),那么您可以创建一个派生类,该类提供stringToUrl返回模拟(或引发异常)的实现。