簡體   English   中英

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

[英]How to mock HttpURLConnection and its responseCode in spock framework

我正在使用 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

但它不起作用。

您的問題有幾處錯誤:

  1. 它由一組不連貫的不完整代碼片段組成,而不是MCVE ,即一個完整的、最小的示例,每個想要幫助您的人都可以編譯和運行,而無需完成您的工作並自己編寫示例類。 那是你的工作。

  2. url.openConnection(_) >> httpURLConnection中,您正在嘗試存根方法結果,但您的URL object 未聲明為模擬、存根或間諜。 即,您的嘗試注定要失敗。

  3. 即使您嘗試模擬URL ,JDK class 也是最終的,即您不能模擬它,因為模擬是子類。

  4. 測試中的 class 通過調用url.openConnection(proxy)獲取HttpURLConnection 由於 (3),該方法不可模擬,因此您應該將連接創建外部化到助手 class ConnectionManager中,然后將模擬實例注入被測 class 以使其可測試。

一般來說,測試是一種設計工具,而不僅僅是用測試覆蓋你的代碼。 如果測試困難,則意味着組件設計耦合太緊。 讓測試使用 TDD(測試驅動開發)或至少測試驅動重構來幫助驅動您的設計,即使后者有點晚並且意味着返工。 如果你更多地解耦你的組件,例如,通過不創建 class 內部依賴的 object 實例,但允許 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
  }
}

在 Groovy web 控制台試試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM