gpt4 book ai didi

rest - 使用/路径变量测试Chi路线

转载 作者:行者123 更新时间:2023-12-01 19:39:42 26 4
gpt4 key购买 nike

我在测试go-chi路线(特别是带有路径变量的路线)时遇到了麻烦。使用go run main.go运行服务器可以正常工作,并且使用path变量对路由的请求的行为符合预期。

在对路由进行测试时,始终会收到HTTP错误:Unprocessable Entity。在注销articleID发生了什么之后,似乎articleCtx无法访问path变量。不知道这是否意味着我需要在测试中使用articleCtx,但是我尝试了ArticleCtx(http.HandlerFunc(GetArticleID))并收到错误消息:
panic: interface conversion: interface {} is nil, not *chi.Context [recovered]
panic: interface conversion: interface {} is nil, not *chi.Context

运行服务器:go run main.go
测试服务器:go test .
我的来源:

// main.go

package main

import (
"context"
"fmt"
"net/http"
"strconv"

"github.com/go-chi/chi"
)

type ctxKey struct {
name string
}

func main() {
r := chi.NewRouter()

r.Route("/articles", func(r chi.Router) {
r.Route("/{articleID}", func(r chi.Router) {
r.Use(ArticleCtx)
r.Get("/", GetArticleID) // GET /articles/123
})
})

http.ListenAndServe(":3333", r)
}

// ArticleCtx gives the routes using it access to the requested article ID in the path
func ArticleCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
articleParam := chi.URLParam(r, "articleID")
articleID, err := strconv.Atoi(articleParam)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}

ctx := context.WithValue(r.Context(), ctxKey{"articleID"}, articleID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}

// GetArticleID returns the article ID that the client requested
func GetArticleID(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
articleID, ok := ctx.Value(ctxKey{"articleID"}).(int)
if !ok {
http.Error(w, http.StatusText(http.StatusUnprocessableEntity), http.StatusUnprocessableEntity)
return
}

w.Write([]byte(fmt.Sprintf("article ID:%d", articleID)))
}

// main_test.go

package main

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)

func TestGetArticleID(t *testing.T) {
tests := []struct {
name string
rec *httptest.ResponseRecorder
req *http.Request
expectedBody string
expectedHeader string
}{
{
name: "OK_1",
rec: httptest.NewRecorder(),
req: httptest.NewRequest("GET", "/articles/1", nil),
expectedBody: `article ID:1`,
},
{
name: "OK_100",
rec: httptest.NewRecorder(),
req: httptest.NewRequest("GET", "/articles/100", nil),
expectedBody: `article ID:100`,
},
{
name: "BAD_REQUEST",
rec: httptest.NewRecorder(),
req: httptest.NewRequest("PUT", "/articles/bad", nil),
expectedBody: fmt.Sprintf("%s\n", http.StatusText(http.StatusBadRequest)),
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ArticleCtx(http.HandlerFunc(GetArticleID)).ServeHTTP(test.rec, test.req)

if test.expectedBody != test.rec.Body.String() {
t.Errorf("Got: \t\t%s\n\tExpected: \t%s\n", test.rec.Body.String(), test.expectedBody)
}
})
}
}

不知道如何继续。有任何想法吗?我想知道 net/http/httptest中是否有关于将 context与测试一起使用的答案,但未发现任何结果。

Go也很新(和 context包),因此,任何代码复习/最佳实践注释都非常受人们欢迎:)

最佳答案

我对命名路径变量有同样的问题。我能够解决它,为我的测试设置路由器。格氏测试显示了一个很好的样本。
Go Chi Sample test with URL params

关于rest - 使用/路径变量测试Chi路线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54580582/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com