我正在為未來的專案撰寫一個簡單的其余樣板,我目前正在為我的控制器進行一些測驗,我正在嘗試通過它的 Id at 檢索待辦事項,這/todo/{id}是處理程式。
func (t TodoController) GetById(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id, err := strconv.Atoi(params["id"])
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
todo, err := t.todoService.GetById(id)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
helpers.SendResponse(http.StatusOK, todo, w)
}
這是這個控制器的測驗。
var (
todoController TodoController
recorder *httptest.ResponseRecorder
todos []models.Todo
)
func setup() {
todoController = *NewTodoController(services.NewTodoService())
recorder = httptest.NewRecorder()
todos = []models.Todo{
{
ID: 0,
Todo: "Buy milk",
Completed: false,
},
{
ID: 1,
Todo: "Buy cheese",
Completed: false,
},
{
ID: 2,
Todo: "Buy eggs",
Completed: false,
},
}
}
func TestGetById(t *testing.T) {
// Arrange
setup()
request := httptest.NewRequest(http.MethodGet, "/todo/1", nil)
var response models.Todo
// Act
todoController.GetById(recorder, request)
result := recorder.Result()
defer result.Body.Close()
data, err := ioutil.ReadAll(result.Body)
err = json.Unmarshal(data, &response)
// Assert
if err != nil {
t.Errorf("Expected error to be nil but got %v", err)
}
assert.Equal(t, result.StatusCode, http.StatusOK, "Response should have been 200 Ok")
assert.Equal(t, response, todos[1], "Response did not match the expected result")
}
看起來向/todo/1mux 發送請求時無法檢索 Id,因此最終回傳 BadRequest 錯誤。
這是此倉庫的鏈接:https ://github.com/Je12emy/rest_boiler
uj5u.com熱心網友回復:
Mux 提供了兩種注入請求引數的方法 -SetURLVars幫助程式和使用mux.Router包裝器而不是直接處理程式呼叫。
SetURLVars完全符合您的要求 - 將其他無法訪問的引數注入 HTTP 請求。
這種方法很簡單,但有一個問題。使用的 URL 和注入的引數不同步。
None 禁止開發人員撰寫此代碼:
// we use 2 in request path
request := httptest.NewRequest(http.MethodGet, "/todo/2", nil)
// and we use 1 in request param
request = SetURLVars(request, map[string]string{"id":"1"})
這不是很干凈的測驗實踐。
我們不測驗路由中的 var 名稱是否正確。我們可以item_id在路由器中使用而不是id測驗并沒有捕捉到這一點。
不僅如此,我們還可以在路由器定義中使用錯誤的路徑并映射不同的處理程式。如果我們犯了這個錯誤,客戶可以洗掉order而不是洗掉專案。todo
如果我們在測驗中使用我們的生產路由器,這可以解決。
假設它是我們的生產代碼:
func InitRouter(t TodoController) http.handler
r := mux.NewRouter()
r.HandleFunc("/todo/{id}", t.GetById).Methods(http.MethodGet)
return r
在測驗中,我們可以GetById通過我們在InitRouter函式中創建的路由器進行測驗:
func TestGetById(t *testing.T) {
// Arrange
setup()
request := httptest.NewRequest(http.MethodGet, "/todo/1", nil)
var response models.Todo
// added setup
sut := InitRouter(todoController)
// Act
// changed act - calling GetById through production router
sut.ServeHTTP(recorder, request)
// no chnages after that
result := recorder.Result()
defer result.Body.Close()
...
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/483695.html
