1

我的代码是 API 的使用者 (www.abc.com/public/news/apple.json)。我得到一个 json 数组作为回报,然后我解析并填充到我自己的数据结构中。负责执行此操作的代码是:

    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();
     }

如您所见,我不是 api 的控制器,只是消费者。据说在单元测试中,不应该发出http请求。在这种情况下,如何对 populateNewsArray() 函数进行单元测试以查看对象映射是否正确(没有任何异常)并返回有效的哈希图?

4

2 回答 2

1

您应该提取getNews()到一个单独的界面,例如 NewsReader(虽然这个词Reader在 JDK 中具有特定的含义,但我喜欢这个名字......)

public interface NewsReader {
    InputStream getNews(String request, boolean bulk) throws Exception
}

然后根据您的代码使用实现该接口HttpURLConnection并更新您的代码以允许注入该特定接口。然后,如果您需要测试您的代码如何处理InputStream,您可以创建一个模拟,NewsReader该模拟返回InputStream具有众所周知的内容的 a 。

请记住以高内聚为目标:您的类不应该是 HTTP 客户端流解析器。

于 2012-09-26T10:54:36.563 回答
0

我会创建一个子类并覆盖方法getNews(...)。然后,在子类中,您可以InputStream为您的测试返回一个。
由于您不应该在单元测试中依赖某些外部文件,并且为了获得更好的可测试设计,我还将更改getNews(...)方法以返回某种可以由映射器进一步处理的值。

于 2012-09-26T10:28:18.743 回答