首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >httptest ResponseRecorder保留旧值

httptest ResponseRecorder保留旧值
EN

Stack Overflow用户
提问于 2021-06-29 10:06:22
回答 1查看 68关注 0票数 0

我有一个需要测试的handlerAuthentication函数:

代码语言:javascript
复制
func handlerAuthentication(c *gin.Context) {
    session := Session.GetSession(c)
    var login Login
    err := c.BindJSON(&login)
    if err != nil {
        c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    client, err := initClient(c, login)
    fmt.Println("Error: ",err)
    if err != nil {
        fmt.Println("There's an error !")
        c.JSON(http.StatusUnauthorized, gin.H{"error": ErrorWrongLogin})
        return
    }
    err = (*client).Logout(c)
    if err != nil {
        return
    }

    session.Set("username", login.Username)
    session.Set("password", login.Password)
    err = session.Save()
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "an error occurred during the save of the session:" + err.Error()})
        return
    }
    c.JSON(http.StatusOK, "Connected")
}

为了做到这一点,我做了以下工作:

代码语言:javascript
复制
func TestHandlerAuthentication(t *testing.T) {
    UrlOdoo = "https://isi.nc"
    resp := httptest.NewRecorder()
    gin.SetMode(gin.TestMode)
    c, r := gin.CreateTestContext(resp)

    r.POST("/test", func(c *gin.Context) {
        handlerAuthentication(c)
    })

    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    Odoo = OdooRPC{createMockOdooClient}
    client = mock_odoorpc.NewMockOdooClient(ctrl)
    client.EXPECT().Authenticate(gomock.Any(), gomock.Any(), invalidUsername, invalidPassword).AnyTimes().Return(fmt.Errorf("invalid login"))
    client.EXPECT().Authenticate(gomock.Any(), gomock.Any(), validUsername, validPassword).AnyTimes().Return(nil)
    client.EXPECT().Logout(gomock.Any()).AnyTimes().Return(nil)

    session = mock_session.NewMockSession(ctrl)
    Session = SessionGetter{createMockSession}
    session.EXPECT().Set("username", validUsername).AnyTimes().Return()
    session.EXPECT().Set("password", validPassword).AnyTimes().Return()
    session.EXPECT().Save().AnyTimes().Return(nil)

    for name, test := range map[string]struct {
        input   Login
        want    int
    }{
        "valid login": {
            input: Login{
                Username: validUsername,
                Password: validPassword,
            },
            want: 200,
        },
        "invalid login": {
            input: Login{
                Username: invalidUsername,
                Password: invalidPassword,
            },
            want: 401,
        },
    } {
        t.Run(name, func(t *testing.T) {
            body, _ := json.Marshal(test.input)
            c.Request, _ = http.NewRequest(http.MethodPost, "/test", strings.NewReader(string(body)))
            r.ServeHTTP(resp, c.Request)
            assert.Equal(t, test.want, resp.Code)
            resp.Flush()
        })
    }
}

我面临的问题是,如果我逐个测试(valid logininvalid login),它们都通过了,但是当我同时执行这两个测试时,第二个测试失败了。下面是同时执行两个测试的示例:

代码语言:javascript
复制
=== RUN   TestHandlerAuthentication
=== RUN   TestHandlerAuthentication/valid_login
Error:  <nil> //No error, so resp.Code should be equal to 200
=== RUN   TestHandlerAuthentication/invalid_login
Error:  invalid login //Error, so resp.Code should be equal to 401
There's an error !
    main_test.go:394: 
            Error Trace:    main_test.go:394
            Error:          Not equal: 
                            expected: 401
                            actual  : 200
            Test:           TestHandlerAuthentication/invalid_login
--- FAIL: TestHandlerAuthentication (0.00s)
    --- PASS: TestHandlerAuthentication/valid_login (0.00s)
    --- FAIL: TestHandlerAuthentication/invalid_login (0.00s)


Expected :401
Actual   :200

不出所料,当登录无效,但resp.Code仍为200时,会发生错误。如果我先做invalid login测试,resp.Code仍然是401。

这是不是因为测试是并行化的,并且httptest ResponseRecorder不能并行工作?

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-29 11:19:19

谢谢你,leaf bebop

我需要为每个测试初始化一个新的httptest.ResponseRecorder。为此,我将初始化移至t.Run(name,func(t *testing.T)函数:

代码语言:javascript
复制
func TestHandlerAuthentication(t *testing.T) {
    UrlOdoo = "https://isi.nc"

    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    Odoo = OdooRPC{createMockOdooClient}
    client = mock_odoorpc.NewMockOdooClient(ctrl)
    client.EXPECT().Authenticate(gomock.Any(), gomock.Any(), invalidUsername, invalidPassword).AnyTimes().Return(fmt.Errorf("invalid login"))
    client.EXPECT().Authenticate(gomock.Any(), gomock.Any(), validUsername, validPassword).AnyTimes().Return(nil)
    client.EXPECT().Logout(gomock.Any()).AnyTimes().Return(nil)

    session = mock_session.NewMockSession(ctrl)
    Session = SessionGetter{createMockSession}
    session.EXPECT().Set("username", validUsername).AnyTimes().Return()
    session.EXPECT().Set("password", validPassword).AnyTimes().Return()
    session.EXPECT().Save().AnyTimes().Return(nil)

    for name, test := range map[string]struct {
        input Login
        want  int
    }{
        "valid login": {
            input: Login{
                Username: validUsername,
                Password: validPassword,
            },
            want: 200,
        },
        "invalid login": {
            input: Login{
                Username: invalidUsername,
                Password: invalidPassword,
            },
            want: 401,
        },
    } {
        t.Run(name, func(t *testing.T) {
            resp := httptest.NewRecorder()
            gin.SetMode(gin.TestMode)
            c, r := gin.CreateTestContext(resp)

            r.POST("/test", func(c *gin.Context) {
                handlerAuthentication(c)
            })

            body, _ := json.Marshal(test.input)
            c.Request, _ = http.NewRequest(http.MethodPost, "/test", strings.NewReader(string(body)))
            r.ServeHTTP(resp, c.Request)
            assert.Equal(t, test.want, resp.Code)
        })
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68171765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档