Java單元測試 Http Server Mock框架選型


背景動機

某期優化需要針對通用的HttpClient封裝組件--HttpExecutor在保證上層暴露API不動的前提做較多改動,大致包括以下幾點:

  • apache http client 版本升級
  • HttpClientBuilder代碼重構
  • RequestBuilder代碼重構
  • 自定義RetryHandler
  • HttpContext擴展
  • 自定義HttpRequestInterceptor/HttpResponseInterceptor

代碼很快修改完了,但是如何保證HttpExecutor的行為和以前是一致的呢?很容易就想到是單元測試。因為以前的代碼並未提供組件的單元測試,都是依賴QA同學的黑盒測試完成,現有的單元測試又都是在更上層的HttpDao上,重點是對返回數據的解析邏輯代碼驗證,直接Mock了HttpExecutor的返回結果,完全無法覆蓋底層組件的請求邏輯,因此配合本期優化需要提供HttpExecutor組件的單元測試。

需求分析

先大致分析一下HttpExecutor組件提供的功能:

  • 注冊apache http client實例的初始化和銷毀,包含ConnectionManager等apache http client子功能組件;
  • 上層入參的轉封裝,以及HttpResponse結果的初步解析封裝(response header、status code、response data);
  • 依賴Interceptor對Http請求進行簡單的統計;
  • 指定IO異常時的重試功能;

從功能上來分析,我需要的框架/組件需要滿足以下功能:

  1. 響應延時;
  2. 異常模擬;
  3. Response Mock;
  4. request verify(請求驗證);
  5. 必須是通過server simulate的方式,而非client stub,即必須真實的發起Http請求;
  6. 足夠輕量,不必通過獨立進程部署;

作為加分項,最好可以提供以下功能:

  1. Record & Replay(記錄真實請求自動生成回放配置,生寫代碼有點痛苦);
  2. 支持json或yaml等非代碼的DSL配置方式;
  3. 和Junit等單元測試框架集成良好;
  4. 支持maven plugin;
  5. 支持版本控制;

選型

從需求分析中必須真實發起請求來看,我的目標就是類似前后端分離開發中常用的API管理平台,這種平台很多,國內的類似小幺雞YApiRap2Eolinker。但這些平台都必須是作為獨立進程部署,而作為單元測試場景,我需要的足夠輕量的部署方式。
照例先google、baidu、stackoverflow、github、mvnrepository上轉一圈,找到了以下幾篇關聯性較強的文章(倉庫):

微服務下的契約測試(CDC)解讀中對契約測試、單元測試、接口測試區別描述中可以發現,契約測試完全能滿足甚至超出我的需求,因此下面的框架選型也從契約測試的方向來出發。

根據文章推薦,篩選出mock-serverokhttp/mockwebserverWireMock

Framework 部署方式 抓取回放請求 代理服務模式 Https/SSL Http2 故障模擬 多語言支持 非代碼配置 生態(其他框架集成) Http Log Response模板
mock-server jar包集成/獨立war包部署/Maven Plugin/Node.js Module/Grunt Plugin/Docker/Kubernetes/Homebrew 等,詳見Running Mock Server 支持 支持 支持 支持 支持響應延時以及500等錯誤響應模擬 支持多語言client(java、ruby、node) json文件配置 - 支持 支持
okhttp/mockwebserver jar包集成 不支持 不支持 - 支持 支持模擬慢速網絡環境以及500等錯誤響應模擬 支持 json文件配置 OKHttp 不支持 不支持
WireMock jar包集成/獨立war包部署 支持 支持 支持 jre8版本支持 支持響應延時以及500等錯誤響應模擬 Node.js json文件配置 spring-cloud-contract 支持 支持

功能特性對比

就支持的功能集來看,okhttp/mockwebserver最弱,WireMockmock-server兩者支持的特性大體相同,但是mock-server支持更多種語言和更多的部署環境,而WireMock則有Spring Cloud Contract的光環加持。

架構依賴對比

okhttp/mockwebserver本身就是OKHttp的mock組件,完全是原生的實現,除了Junit幾乎沒有其他依賴,是3個框架里最輕量的,詳見mockwebserver/4.2.2

mock-server使用netty作為http server,最大的依賴項就是netty,其他還有一些guava、commons-collection4、jackson等依賴,詳見mockserver-core/5.6.1

WireMock使用jetty作為http server,是典型的servlet架構,其他還依賴guava、jackson、httpclient等,詳見wiremock-jre8/2.25.0

流行度對比

google trends結果顯示WireMock更流行,而npm trends的結果正好相反,npm trends上mock-server的流行度可謂完全碾壓WireMock,可能和mock-server對多語言的支持以及豐富的部署環境支持有關。

總結

我們知道框架選型永遠都是根據選型人員、代碼現狀、需求場景來決定的,因此我這里只做推薦,不說結論。

如果你只是需要簡單的HTTP Server Simulator輔助業務邏輯測試,無需SSL協議支持,那我推薦你使用okhttp/mockwebserver,功能夠用,十分輕量,而且是OKHttp的組件,如果是Android開發那使用正好(Android上OKHttp使用率碾壓HttpClient)。

如果你已經有很多Http API在運行,希望使用Record & Replay簡化Mock DSL的編寫,那么mock-serverWireMock都能滿足你。

如果你的測試場景包含UI/UX測試,那支持node.js的mock-server對前端開發更為友好。又或者你的真實server是netty,不想引入servlet架構。

如果你是單純的Java API測試,並且你還使用了Spring Cloud技術棧,那么WireMockSpring Cloud Contract是很合適的選擇。

最后,附上一篇自己實現Mock Server的參考文檔Using Sun Java 6 HttpServer to write a functional HTTP test


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM