gin
思路
參考相關文件、 repo ,在設計上的層級類似下列這樣
server => service (interface) => repository (interface)
將 interface 開出來,實作完之後一路使用注入的逐層掛進去。
開出 interface 除了規範 method 之外,還能在後續針對測試時, 方便撰寫 mock 注入。
server
| - service
| - repository
略
測試
以使用 gin 為例
get
const wantGetMsg = "mock hello eric"
func TestHelloByName(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.Default()
// di mock service
service := MockHelloService{}
server := NewHelloServer(service)
// mount router
r.GET("/hello/:name", server.SayHello)
rq := httptest.NewRequest(http.MethodGet, "/hello/eric", nil)
rw := httptest.NewRecorder()
r.ServeHTTP(rw, rq)
if rw.Body.String() != wantGetMsg {
t.Errorf("want: %q , get: %q", wantGetMsg, rw.Body.String())
}
}
post form-data
header 要帶
rq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
const wantPostMsg = "mock post my first post"
func TestPostFormData(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.Default()
service := MockHelloService{}
server := NewHelloServer(service)
r.POST("/msg", server.SayPost)
formPayload := url.Values{}
formPayload.Set("msg", "my first post")
rq := httptest.NewRequest(http.MethodPost, "/msg", strings.NewReader(formPayload.Encode()))
rq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
rw := httptest.NewRecorder()
r.ServeHTTP(rw, rq)
if rw.Body.String() != wantPostMsg {
t.Errorf("want: %q , get: %q", wantPostMsg, rw.Body.String())
}
}
post json
有兩種方式帶 json
- 直接用 json string 轉成 byte
- struct 透過 json.Marshal 轉成 byte
要記得帶上
rq.Header.Add("Content-Type", "application/json")
const wantPostJsonMsg = "mock json my name eric"
func TestPostJson(t *testing.T) {
gin.SetMode(gin.TestMode)
r := gin.Default()
hs := MockHelloService{}
ss := NewHelloServer(hs)
r.POST("/json", ss.SayJson)
sendJson := map[string]interface{}{
"name": "eric",
}
b, _ := json.Marshal(sendJson)
rq := httptest.NewRequest(http.MethodPost, "/json", bytes.NewBuffer(b))
rq.Header.Add("Content-Type", "application/json")
rw := httptest.NewRecorder()
r.ServeHTTP(rw, rq)
if rw.Body.String() != wantPostJsonMsg {
t.Errorf("want: %q , get: %q", wantPostJsonMsg, rw.Body.String())
}
}
參考文件
- Revisiting HTTP Handlers
- 04 - Testing A Gin HTTP Handler With Testify Mock
- github.com/JacobSNGoodwin/memrizr