gpt4 book ai didi

unit-testing - 具有自定义 ServeHTTP 实现的 http 处理程序的 golang 单元测试

转载 作者:数据小太阳 更新时间:2023-10-29 03:32:40 31 4
gpt4 key购买 nike

我正在尝试为我的 http 文件服务器编写单元测试。我已经实现了 ServeHTTP 函数,以便它在 URL 中用“/”替换“//”:

type slashFix struct {
mux http.Handler
}

func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) {
r.URL.Path = strings.Replace(r.URL.Path, "//", "/", -1)
h.mux.ServeHTTP(w, r)
}

最低限度的代码如下所示:

func StartFileServer() {
httpMux := http.NewServeMux()
httpMux.HandleFunc("/abc/", basicAuth(handle))
http.ListenAndServe(":8000", &slashFix{httpMux})
}

func handle(writer http.ResponseWriter, r *http.Request) {
dirName := "C:\\Users\\gayr\\GolandProjects\\src\\NDAC\\download\\"
http.StripPrefix("/abc",
http.FileServer(http.Dir(dirName))).ServeHTTP(writer, r)
}

func basicAuth(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if user != "UserName" || pass != "Password" {
w.WriteHeader(401)
w.Write([]byte("Unauthorised.\n"))
return
}
handler(w, r)
}
}

我在测试 http 处理程序时遇到了如下实例:

req, err := http.NewRequest("GET", "/abc/testfile.txt", nil)
if err != nil {
t.Fatal(err)
}
req.SetBasicAuth("UserName", "Password")
rr := httptest.NewRecorder()
handler := http.HandlerFunc(basicAuth(handle))
handler.ServeHTTP(rr, req)

这样做会调用使用 http.HandleFunc 实现的 ServeHTTP 函数,但我希望调用在我的代码中实现的 ServeHTTP。如何实现?还有,有没有办法让我直接测试StartFileServer()?

编辑:我检查了评论中提供的链接;我的问题似乎没有重复。我有一个具体问题:我希望调用在我的代码中实现的 ServeHTTP,而不是调用使用 http.HandleFunc 实现的 ServeHTTP 函数。我没有在提供的链接中看到这个问题。

最佳答案

http.HandlerFunc 实现了 http.Handler。正如 Flimzy 在评论中指出的那样,basicAuth 不需要 HandlerFunc;任何 http.Handler 都可以。坚持使用 http.Handler 接口(interface)而不是具体的 HandlerFunc 类型将使一切都易于组合:

func basicAuth(handler http.Handler) http.Handler { // Note: http.Handler, not http.HandlerFunc
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok {
// TODO
}
if user != "UserName" || pass != "Password" {
w.WriteHeader(401)
w.Write([]byte("Unauthorised.\n"))
return
}

handler.ServeHTTP(w, r)
})
}

func TestFoo(t *testing.T) {
req, err := http.NewRequest("GET", "/abc/testfile.txt", nil)
if err != nil {
t.Fatal(err)
}
req.SetBasicAuth("UserName", "Password")
rr := httptest.NewRecorder()

// composition is trivial now
sf := &slashFix{
mux: http.HandlerFunc(handle),
}
handler := basicAuth(sf)
handler.ServeHTTP(rr, req)

// assert correct rr
}

关于unit-testing - 具有自定义 ServeHTTP 实现的 http 处理程序的 golang 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50964832/

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