Java 单元测试webapi消费模块
我的代码是API的使用者(www.abc.com/public/news/apple.json)。作为回报,我得到一个json数组,然后将其解析并填充到我自己的数据结构中。负责执行此操作的代码是:Java 单元测试webapi消费模块,java,api,unit-testing,Java,Api,Unit Testing,我的代码是API的使用者(www.abc.com/public/news/apple.json)。作为回报,我得到一个json数组,然后将其解析并填充到我自己的数据结构中。负责执行此操作的代码是: public Map<String,List<NewsItem>> populateNewsArray() throws Exception { url = domain + newsApiStr; Inp
public Map<String,List<NewsItem>> populateNewsArray() throws Exception
{
url = domain + newsApiStr;
InputStream stream = getNews(url, true);
//jackson library object mapper
ObjectMapper mapper = new ObjectMapper();
//NewsApiObject class implements the structure of the json array returned.
List<NewsApiObject> mappedData = mapper.readValue(stream, NewsApiObject.class));
//populate the properties in a HashMap.
//return HashMap
}
public InputStream getNews(String request, boolean bulk) throws Exception
{
URL url = new URL(request);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("charset", "utf-8");
connection.connect();
return connection.getInputStream();
}
公共映射PopulateNewArray()引发异常
{
url=domain+newsApiStr;
InputStream=getNews(url,true);
//jackson库对象映射器
ObjectMapper mapper=新的ObjectMapper();
//NewsApiObject类实现返回的json数组的结构。
List mappedData=mapper.readValue(stream,NewsApiObject.class));
//在HashMap中填充属性。
//返回哈希映射
}
公共InputStream getNews(字符串请求,布尔批量)引发异常
{
URL=新URL(请求);
connection=(HttpURLConnection)url.openConnection();
connection.setDoOutput(真);
connection.setInstanceFollowDirections(false);
connection.setRequestMethod(“GET”);
setRequestProperty(“内容类型”、“文本/普通”);
setRequestProperty(“字符集”、“utf-8”);
connection.connect();
返回连接。getInputStream();
}
正如您所看到的,我不是api的控制器,只是消费者。据说,在单元测试中,不需要进行http请求。在这个场景中,如何对populateNewsArray()函数进行单元测试,以查看对象映射是否正确(没有任何异常),以及是否返回了有效的hashmap 我将创建一个子类并覆盖方法
getNews(…)
。在子类中,您可以为测试返回一个InputStream
。由于在单元测试中不应该依赖于某些外部文件,并且为了获得更好的可测试设计,我还将更改
getNews(…)
方法以返回某种类型的值,这些值可以由映射程序进一步处理。我将创建一个子类并覆盖该方法getNews(…)
。在子类中,您可以为测试返回一个InputStream
。由于在单元测试中您不应该依赖于某些外部文件,并且为了获得更好的可测试设计,我还将更改
getNews(…)
方法以返回某种类型的值,这些值可以由映射程序进一步处理。您应该将getNews()
提取到单独的接口中,例如新闻阅读器(虽然单词Reader
在JDK中有特定的含义,但我喜欢这个名字…)
然后根据您的代码使用HttpURLConnection
实现该接口,并更新您的代码以允许注入该特定接口。然后,如果您需要测试代码如何处理InputStream
,您可以创建一个模拟的NewsReader
,它返回一个InputStream
,其中包含已知的con帐篷
请记住要以高内聚性为目标:您的类不应该是HTTP客户端和流解析器。您应该将
getNews()
提取到一个单独的接口中,例如新闻阅读器(尽管Reader
这个词在JDK中有特定的含义,我喜欢这个名称…)
然后根据您的代码使用HttpURLConnection
实现该接口,并更新您的代码以允许注入该特定接口。然后,如果您需要测试代码如何处理InputStream
,您可以创建一个模拟的NewsReader
,它返回一个InputStream
,其中包含已知的con帐篷
请记住要以高内聚性为目标:您的类不应该是HTTP客户端和流解析器。顺便说一句,david,如果我确实创建了一个新闻阅读接口,那么我如何测试PopulateWarray()func?我是否需要完全更改函数并删除getNews调用,以便对其进行单元测试?@Salmanmahmood
PopulatenWarray
调用NewsReader.getNews
。您可以插入一个返回ByteArrayInputStream
包含已知JSON。如何确保在测试时调用模拟对象,而不是真正的实现(进行网络调用)?使用依赖项注入。您可以手动执行,也可以使用IoC容器(Spring/Guice)。这里的关键概念是将新闻阅读器注入到类中。例如,在主类中定义一个构造函数,该构造函数接受新闻阅读器实例。顺便说一句,david,如果我确实创建了一个用于新闻阅读的接口,那么我如何测试populateNewArray()func?我是否需要完全更改函数并删除getNews调用,以便对其进行单元测试?@SalmanmahmoodPopulatenWarray
调用NewsReader.getNews
。您可以插入一个返回ByteArrayInputStream
包含已知JSON。如何确保在测试时调用模拟对象,而不是真正的实现(进行网络调用)?使用依赖项注入。您可以手动执行,也可以使用IoC容器(Spring/Guice)。这里的关键概念是将新闻阅读器注入到类中。例如,在主类中定义一个构造函数,该构造函数接受新闻阅读器实例。
public interface NewsReader {
InputStream getNews(String request, boolean bulk) throws Exception
}