模拟处理程序单元测试的函数

时间:2018-02-12 12:29:46

标签: unit-testing go mocking

我坚持用模拟测试,这是我的处理程序路径:

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)这样的网址,但是当我在内部使用链接时,我无法使用模拟功能,这里我缺少/错误请帮助我。 谢谢。

1 个答案:

答案 0 :(得分:0)

使用中间件处理程序生成函数。在main函数中传递一个处理程序,它将调用您的中间件返回http.handler。这样你就可以将db对象传递给主数据,并调用中间件返回处理程序。

func getUserDetailsHandler(w http.ResponseWriter, r *http.Request, db *sql.DB) http.HandlerFunc{

    return func(w http.ResponseWriter, r *http.Request) {

        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)
   }
}