前言
HTTP 搭配 TCP/IP 來運作是常見的案例,但實際上 HTTP 本身只假定下層協定會提供可靠的傳輸,所以只要任何滿足可靠傳輸的協定都能成為 HTTP 的下層。在行程間通訊 (IPC, Inter-Process Communication) 應用情境中,較常使用 Unix Domain Socket (UDS) 來取代 TCP/IP,例如:docker 指令透過 Docker Server 建立的 UDS 發送 HTTP Request 給 Docker Server。因此,對開發者來說,知道如何對使用 UDS 作為下層傳輸協定的 HTTP Client 進行測試是重要的。
環境
- go version go1.19.3
測試手段的選擇
在 [Golang] HTTP Client Unit Test by Mock HTTP Server 一文中已詳細說明不同測試手段的優缺點,這裡同樣會使用 Unit Test by Mock HTTP Server 的手法來撰寫測試案例!
情境說明
API Server (/var/mysock.sock
) 提供兩個端點 (Endpoints) 讓我們可以取得或操作使用者相關資訊。
GET /api/v1/users
取得使用者資訊請求成功:回傳 200 OK 狀態碼與所有使用者的名稱
1
2
3
4
5[
"Jack",
"Marry",
"Sandy"
]請求失敗:回傳 4xx 或 5xx 狀態碼並帶著錯誤訊息
1
2
3{
"msg": "something wrong!"
}
POST /api/v1/user
創建使用者請求格式:
Content-Type
需為application/json
,且 playload 格式如下1
2
3{
"name": "Jack"
}請求成功:回傳 201 Created 狀態碼與該使用者相關資訊
1
2
3
4{
"id": "ABC-111",
"name": "Jack"
}請求失敗:回傳 4xx 或 5xx 狀態碼並帶著錯誤訊息
1
2
3{
"msg": "something wrong!"
}
這是虛構出來的情境,我們著重在於 HTTP Client 的測試,至於 HTTP Server 是否存在並不會影響到我們的測試結果,所以這裡不會關心 Server 的實作!
HTTP Client 撰寫與測試
Source Code 已上傳於 GitHub,歡迎自行 Clone/Fork 來運行!以下摘錄重要的部分,每一行代碼的作用皆詳細註解在程式碼中,請耐心閱讀、吸收並化為自身內力。
取得使用者資訊
1 | type errorResponse struct { |
1 | // NewUnixDomainSocketServer starts and returns a new Server based |
創建使用者
1 | type CreateUserRequest struct { |
1 | // NewUnixDomainSocketServer starts and returns a new Server based |
不難看出 NewUnixDomainSocketServer
是我們撰寫測試的關鍵,因為 httptest
官方套件並沒有提供 UDS-based HTTP Server,所以我們透過 net.Listen
建立一個 UDS Connection,再將該 Connection 提供給 httptest.Server
改變底層的傳輸協定,最後啟動 Server 作為測試用的 UDS-based Mock HTTP Server!
結語
Golang 官方與社群的力量雖然強大,但並不是每個功能都會有的,所以我們除了學會使用既有的 Library,同樣需要理解這些代碼背後的原理,才能站在巨人肩膀上來根據需求衍生出新的功能。倘若心有餘力,我們可以將新功能回饋給社群,形成良好的循環!