groovy 如何在spock框架中模拟HttpURLConnection及其responseCode

rqqzpn5f  于 7个月前  发布在  其他
关注(0)|答案(1)|浏览(103)

我正在使用Java,并在Groovy中使用Spock框架编写junit,希望根据不同情况模拟HttpUrlConnection并设置connection.getResponseCode()>> 200。

URL url = new URL(proxySettingDTO.getTestUrl());
HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
connection.setRequestMethod("GET");
connection.setUseCaches(false);
...
LOGGER.debug("Response code ::{} ",connection.getResponseCode()); //200 or 403

字符串
我试过用

HttpURLConnection httpURLConnection = Mock()
URL url = new URL(proxySettingDTO.getTestUrl());
url.openConnection(_) >> httpURLConnection


但它不起作用。

xqk2d5yq

xqk2d5yq1#

你的问题有几个地方不对:
1.在url.openConnection(_) >> httpURLConnection中,你试图stub一个方法的结果,但是你的URL对象没有被声明为mock、stub或spy。也就是说,你的尝试注定要失败。
1.即使你试图模拟一个URL,这个JDK类也是final的,也就是说,你不能模拟它,因为模拟是子类。
1.被测类通过调用url.openConnection(proxy)获取HttpURLConnection。由于(3),该方法不可模拟,因此您应该将连接创建外部化到助手类ConnectionManager中,然后将模拟示例注入到被测类中,以使其可测试。
一般来说,测试是一种设计工具,而不仅仅是用测试覆盖代码。如果测试很困难,这意味着组件设计耦合得太紧。让测试帮助驱动使用TDD的设计。(测试驱动的开发)或者至少是测试驱动的重构,尽管后者有点晚,而且意味着返工。如果你更多地解耦你的组件,例如,通过不创建你的类内部依赖的对象示例,而是允许API用户注入它们,例如通过构造器或设置器,可测试性要好得多,你有更少的麻烦。
这个怎么样?

class UnderTest {
  private Proxy proxy
  private ProxySettingDTO proxySettingDTO
  private ConnectionManager connectionManager
   UnderTest(Proxy proxy, ProxySettingDTO proxySettingDTO, ConnectionManager connectionManager) {
    this.proxy = proxy
    this.proxySettingDTO = proxySettingDTO
    this.connectionManager = connectionManager
  }

  int getConnectionResponseCode() {
    URL url = new URL(proxySettingDTO.getTestUrl())
    HttpURLConnection connection = (HttpURLConnection) connectionManager.openConnection(url, proxy)
    connection.setRequestMethod("GET")
    connection.setUseCaches(false)
    connection.getResponseCode()
  }
}
class ProxySettingDTO {
  String getTestUrl() {
    "https://scrum-master.de"
  }
}
class ConnectionManager {
  URLConnection openConnection(URL url, Proxy proxy) {
    url.openConnection(proxy)
  }
}
package de.scrum_master.stackoverflow.q71616286

import spock.lang.Specification

class HttpConnectionMockTest extends Specification {
  def test() {
    given: "a mock connection manager, returning a mock connection with a predefined response code"
    ConnectionManager connectionManager = Mock() {
      openConnection(_, _) >> Mock(HttpURLConnection) {
        getResponseCode() >> 200
      }
    }

    and: "an object under test using mock proxy, real DTO and mock connection manager"
    def underTest = new UnderTest(Mock(Proxy), new ProxySettingDTO(), connectionManager)

    expect: "method under test returns expected response"
    underTest.getConnectionResponseCode() == 200
  }
}

Try it in the Groovy web console.

相关问题