Junit:如何模拟HttpUrlConnection

3
如何模拟 HttpURLConnection 中的 getContent() 方法,在示例代码中,还有如何从模拟 URL 获取响应。
public class WebClient {
   public String getContent(URL url) {
       StringBuffer content = new StringBuffer();
       try {

           HttpURLConnection connection = createHttpURLConnection(url);
           connection.setDoInput(true);
           InputStream is = connection.getInputStream();
           int count;
           while (-1 != (count = is.read())) {
               content.append(new String(Character.toChars(count)));
           }
       } catch (IOException e) {
           return null;
       }
       return content.toString();
   }
   protected HttpURLConnection createHttpURLConnection(URL url) throws IOException{
       return (HttpURLConnection)url.openConnection();

   } 
}

谢谢

3个回答

2
您的Webclient设计不太适合测试。您应该避免隐藏依赖项(基本上是大多数new操作)。为了能够进行模拟,这些依赖项应该在对象的构造函数中(最好是)给予对象或对象应该将它们保存在字段中以便进行注入。
或者您可以扩展您的Webclient,如下所示:
new Webclient() {
  @Override
  HttpURLConnection createHttpURLConnection(URL url) throws IOException{
    return getMockOfURLConnection();
}

在这里,getMockOfURLConnection返回一个来自Mockito等模拟框架的HttpURLConnection的模拟对象。然后你需要教会这个模拟对象返回你想要的内容,并使用verify来检查它是否被正确调用。


2
你应该重构你的代码:使用方法URL.openStream()代替这个强制转换为HttpURLConnection。代码会更简单、更通用且更易于测试。
public class WebClient {
    public String getContent(final URL url) {
        final StringBuffer content = new StringBuffer();
        try {
            final InputStream is = url.openStream();
            int count;
            while (-1 != (count = is.read()))
                content.append(new String(Character.toChars(count)));
        } catch (final IOException e) {
            return null;
        }
        return content.toString();
    }
}

接下来,你需要模拟URL。由于这是一个最终类,因此无法使用Mockito对其进行模拟。有以下几种解决方案,按优先级排序:

  1. 在类路径中使用虚假资源,然后使用WebClientTest.class.getResource("fakeResource")获取URL
  2. 提取一个名为StreamProvider的接口,允许从URL中获取InputStream并将其注入到您的WebClient中。
  3. 使用PowerMock来模拟final class URL

如果我没错的话,这个解决方案只适用于GET请求。对于POST请求,我确实需要一个HTTPUrlConnection对象来设置方法和正文。 - luca.vercelli

0
你需要使用存根(stubs)来完成这个任务,可以看一下mockito.org,它是一个易于使用的框架。其思想是模仿类的行为,并验证你的代码是否处理了正面和负面的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接