如何減少系統間的依賴 — Mock Server
這篇文章主要解決一個問題: 減少服務系統間依賴關係, 讓開發或是測試可以獨立的進行下去,
要解決這個問題, 我們利用到”模擬”的方式, 也就是 “Mock” Server,
文章介紹幾種容易使用的工具達到模擬服務的目的
解決問題場景
當測試或是開發一個複雜系統的時候, 該系統可能有 A, B 後端服務所組成,
另外用戶端有各種平台C, D等
那麼是不是整体(A, B, C, D)開發完之後才能夠進行整合測試?
如果其中的組件(A or C)進行修改是否測試工作必須延後?
這篇文章筆者建議幾種比較容易上手的三種 “Mock” Server 的方式
假設我們的系統場景如下:
- Web Service A < —– HTTP REST API———-> Client B
單純的 Web Service A 透過 HTTP Rest API 與 用戶端 Client B 溝通
這個場景下,
當 Web Service A 還沒有開發完成, Client B已經完成, ClientB可否先驗證? ClientB如何進行與後端平台進行測試, ?
(反之相同: 當 Web Service A 已經開發完成, Client B 還沒有完成的情況下, Web service A 的功能可否先驗證?)
在 Web Service A 尚未完全開發完成的情況下, 我們就可以使用 Mock service 來模擬部分 Web Service A 的功能
- Web Service A (未開發完成) < —– HTTP REST API———-> Client B (已經完成)
- Web Service A (Mock Server) < —– HTTP REST API———-> Client B (已經完成)
參考一個美團系統案例
https://tech.meituan.com/mock-server-in-action.html
Mock Server = 服務造假?
透過 Mocker Server 來模擬或是取代原本真實 Web Service A 回應用戶端 client B 這樣是不是造假?
直白的觀點, 是的. 既然是造假的一種, 這樣測試有意義嗎?
這個觀點回到協議本身的定義
Web Service A 與 client B 的溝通, 往返的請求與回覆一定是基於定義好的協議
也因此, 當我們在模擬 Web Service A 的時候, 關鍵是也必須定義好與原本 Web Service A 相同的協議
例如
- Client B 請求 user = A, Web Service A 回覆 John
- Client B 請求 City = New York, Web Service A 回覆 USA
所以在”造假”這個 Mock Server 的時候, 就必須將這樣的請求與對應的回覆定義好
因此, Client B 用戶端就可以與這個”造假” Mock 的後端服務進行測試
等到真實的 Web Service A 完成時候, 一樣的再進行整合測試
整個測試的接口沒有受到改變, 測試的依賴性降低, 也不需要等待 Web Service A 完成與否, 可以獨立的測試 Client B
創建 Mock Server 思路
要模擬一個服務主要有兩個關鍵:
- 定義預期的請求, 也就是模擬的服務預期會收到什麼
- 定義預期的返回響應, 也就是收到每一個 Web Service API 時, 回覆的內容
參考: http://www.mock-server.com/
問題來了,
- 有什麼比較簡單的方式可以很快的創建這樣的 Mock Server 呢?
- 可不可以錄製原本真實服務與用戶端的溝通, 把這錄製下來的請求與回覆當作是 Mock Server 的請求回覆定義呢?
第一種快速搭建 Mock Server方式 – Moco
環境搭建只需四個步驟
- 1. 下載 Standalone Moco Runner or OSX 可以
brew install moco
- 2. 編寫**.json (例如儲存為: APIdef.JSON) 也就是定義Mock Server 收到請求後的響應 (犯例如下:)
[ { "response" : { "text" : "Hello, Moco" } } ] |
- 3. 啟動該Mock Server
java -jar moco-runner-<version>-standalone.jar http -p 12306 -c APIdef.JSON
- 4. 測試, 用瀏覽器連接到該Mock Server, http://localhost:12306, 我們應該就會收到 “Hello, Moco”的回覆
如果我想要模擬更複雜一點的服務端行為呢?
可以參考: https://github.com/dreamhead/moco/blob/master/moco-doc/apis.md
另外Mock支援下列服務
- HTTP APIs
- Socket APIs
- REST API
Moco HTTPS 服務
啟動 HTTPS服務需要先生成證書, 之後用下列方式啟動
java -jar <path-to-moco-runner> https -p <monitor-port> -c < configuration -file> --https <path-to-cert.jks > --cert mocohttps --keystore mocohttps
<path-to-moco-runner>
:moco-runner-0.12.0-standalone.jar包路徑<monitor-port>
:http服務 port<configuration -file>
:配置文件路徑, 例如 APIdef.JSON<path-to-cert.jks>
:證書路徑
官方網站: https://github.com/dreamhead/moco
另外 Moco 也可以在 Java Junit Testing 中直接編碼使用
這邊舉幾個定義請求返回的範例
正規表示法範例1
Mock Server 定義編輯 APIdef.JSON
{ “request”: { “uri”: { “match”: “/SearchBook/\\w+” } }, “response”: { “text”: “This is a Book.” } } |
對於用戶端來說, 當發起下列請求時
用戶端發起請求 | 用戶端收到回覆 |
http://localhost:12306/books/SearchBook/*** | This is a Book. |
Template 動態返回參數範例2
Mock Server 定義編輯 APIdef.JSON
|
用戶端請求返回
用戶端發起請求 | 用戶端收到回覆 |
http://localhost:12306/template?name=Book1 | 用戶端會收到Book1 |
ReDirect範例3
也可以用在將請求 ReDirect 的行為, 例如需要登入驗證的頁面, 如果未登入時將頁面導至登入頁面
Mock Server 定義編輯 APIdef.JSON
|
用戶端請求返回
用戶端發起請求 | 用戶端收到回覆 |
http://localhost:12306/redirect | 用戶端頁面會被導到www.google.com |
其他相關基礎範例參考: http://blog.hanschen.site/2016/06/20/moco.html
用户端工具 – PostMan
更強大的Mocker Server