【发布时间】:2018-07-22 15:02:57
【问题描述】:
我被模拟测试卡住了,这是我的处理程序路线:
r.Handle("/users/{userID}", negroni.New(
negroni.HandlerFunc(validateTokenMiddleware),
negroni.Wrap(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
getUserDetailsHandler(w, r, db)
})),
)).Methods("GET")
这是我的处理程序:
func getUserDetailsHandler(w http.ResponseWriter, r *http.Request, db *sql.DB) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
//Create UserDetailsView instance
var userview UserDetailsView
//Get varibale from mux
vars := mux.Vars(r)
//UserID fetches userId from vars
userID := vars["userID"]
//Get user Information by wpUsersID
wuis := store.NewWpUserInformationStore(db)
userInformation, _:= wuis.GetByID(uID)
json.NewEncoder(w).Encode(userview);
//Print result
w.WriteHeader(http.StatusOK)
}
我模拟了存储包中名为GetByID 的函数,它看起来像这样:
type wpUserInfoMockStore struct {
mock.Mock
}
func (m *wpUserInfoMockStore) GetByID(user *WpUserInformation) error {
rets := m.Called(user)
return rets.Error(0)
}
//InitMockStore store
func InitMockStore() *wpUserInfoMockStore {
s := new(wpUserInfoMockStore)
//store = s
return s
}
我为处理程序编写测试用例,但出现错误cannot convert getUserDetailsHandler (type func(http.ResponseWriter, *http.Request, *sql.DB)) to type http.HandlerFunc,但我找不到它发生的原因,这里我使用此https://github.com/sohamkamani/blog_example__go_web_db 的参考,这是我的测试用例代码:
func TestGetUserDetailsTes(t *testing.T) {
// Initialize the mock store
mockStore := store.InitMockStore()
mockStore.On("GetByID").Return([]*store.WpUserInformation{{
21,
sql.NullString{String: "john"},
sql.NullString{String: "Sorensen"},
0}}, nil).Once()
req, err := http.NewRequest("GET", "", nil)
//if requests gives error
if err != nil {
panic(err.Error())
}
//parameters for generateTestUserJWT are set
testUser.ID = "22"
testUser.UserName = "johns"
testUser.Depot = "NYC"
//JWT generated
refToken, err := generateTestJWT(testUser, false)
//handling error while generating token
if err != nil {
panic(err.Error())
}
//token returned is concatenated with Bearer string
newToken = "Bearer " + refToken
//request authorization header is set
req.Header.Set("Authorization", newToken)
req.Header.Set("Latitude", "123.12")
req.Header.Set("Longitude", "456.45")
//response is set
w := httptest.NewRecorder()
hf := http.HandlerFunc(getUserDetailsHandler)
hf.ServeHTTP(w, req)
//if response code is not statusOK then test fails
if w.Code != http.StatusOK {
t.Errorf("/users/{userID} GET request failed, got: %d, want: %d.", w.Code, http.StatusOK)
}
}
如您所见,我测试了没有像 req, err := http.NewRequest("GET", "", nil) 这样的 URL 的处理程序,但是当我在内部使用链接时,我无法使用模拟函数,这里我缺少什么/错误请帮助我。
谢谢。
【问题讨论】:
-
测试中
hf := http.HandlerFunc(getUserDetailsHandler)所在的行导致了恐慌,这应该从您未包含的堆栈跟踪中清楚地看出。现在它出现恐慌的原因是因为您的getUserDetailsHandler函数的签名与http.HandlerFunc函数类型的签名不同。所以基本上你有两种不同的类型,你试图将一种转换为另一种,这是不可能的,所以你会感到恐慌。 -
我该如何解决这个问题,请您编写一些代码来从测试用例调用处理程序。谢谢。
-
实际上,如果函数
store.NewWpUserInformationStore(db)已经返回使用mockStore实例的内容,您应该能够做到这一点 play.golang.org/p/_cFR3vyjkPr。但是正如您从代码示例中看到的那样,为了避免恐慌,您只需将处理程序包装在一个函数中,就像您在问题顶部的代码 sn-p 中所做的那样。
标签: unit-testing go mocking