返回顶部
首页 > 资讯 > 后端开发 > GO >测试中 mux.Vars() 返回的是 nil,而不是预期的映射对象
  • 332
分享到

测试中 mux.Vars() 返回的是 nil,而不是预期的映射对象

2024-04-04 23:04:05 332人浏览 独家记忆
摘要

哈喽!今天心血来潮给大家带来了《测试中 mux.Vars() 返回的是 nil,而不是预期的映射对象》,想必大家应该对golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正

哈喽!今天心血来潮给大家带来了《测试中 mux.Vars() 返回的是 nil,而不是预期的映射对象》,想必大家应该对golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万别错过这篇文章~希望能帮助到你!

问题内容

我在返回 *mux.router 的函数内设置了 gorilla mux 路由器,如下所示

func makeapp(services service.service, pe policyenforce) *mux.router {
    app := mux.newrouter()

    app.notfoundhandler = &notfound{}

    app.use(token.tokenmiddleware)

    # ...
    
    app.methods(Http.methodpost).path("/api/v1/subscription/{emisor}/mh").handlerfunc(makeupdatemh(services, pe))
    app.methods(http.methodget).path("/api/v1/subscription/{emisor}/mh").handlerfunc(makegetmh(services, pe))
    app.methods(http.methodpost).path("/api/v1/subscription").handlerfunc(makecreatesubscription(services, pe))
    app.methods(http.methodget).path("/api/v1/subscription/{emisor}").handlerfunc(makegetsubscription(services, pe))
    
    # ...

    return app
}

因此,在我的测试中,我准备了带有 url 的句柄并运行它:

func (suite *apptestsuite) testupdatemh() {
    args := &service.updatemhinput{
        usuario:     new(string),
        clave:       new(string),
        pin:         new(string),
        certificado: new(string),
        actividades: []string{},
    }
    reader, err := makebody(args)
    suite.noerror(err)

    handle := token.tokenmiddleware(transport.makeupdatemh(suite._s, suite.pe))

    req := httptest.newrequest(http.methodput, "/api/v1/subscription/-/mh", reader)
    w := httptest.newrecorder()

    t := gentoken([]v43.rol{
        {
            nombre: "mh",
            permisos: []v43.permiso{{
                sujeto: permission.mhcredentials,
                accion: permission.update,
            }},
        },
    })
    req.header.add("authorization", t)

    // configura repository
    suite.r.on("updateissuermh", emisor, args.usuario, args.clave, args.pin, args.certificado, args.actividades).return(v43.grupo{}, nil)
    handle.servehttp(w, req)

    resp := w.result()

    suite.equal(http.statusok, resp.statuscode, resp.status)
}

手柄内部看起来像这样:

func MakeUpdateMH(s service.Service, p PolicyEnforce) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        emisor := mux.Vars(r)["emisor"]

        // revisa permisos
        permitido := p.TienePermiso(r.Context(), permission.MHCredentials, permission.Update) && p.PuedeActuarSobreEmisor(r.Context(), emisor)
        if !permitido {
            reportError(w, fault.ErrPermissionDenied, http.StatusForbidden, fault.MessageForbidden, fault.MessageForbidden)
            return
        }
        // cambia el emisor afectado por aquel obtenido de la URL
        if emisor != "-" || emisor == "" {
            emisor = token.GetSub(r.Context())
        }

        var input service.UpdateMHInput
        dec := JSON.NewDecoder(r.Body)
        err := dec.Decode(&input)
        if err != nil {
            http.Error(w, fault.NewBackendError("no se pudo decodificar solicitud: %v", err).Error(), http.StatusBadRequest)
            return
        }

        output, err := s.UpdateMHCredentials(emisor, input.Usuario, input.Clave, input.Pin, input.Certificado, input.Actividades)
        if err != nil {
            http.Error(w, fault.NewBackendError("Error al actualizar credenciales de MH: %v", err).Error(), http.StatusInternalServerError)
            return
        }

        enc := json.NewEncoder(w)
        enc.Encode(output)
    }
}

并且我注意到 mux.vars(r) 返回 nil 而不是值映射,其中应该包含 {"emisor": "-"} 并且我无法理解为什么情况并非如此.

我已经在处理 "emisor" 为空时的情况,但对于不能使用“-”或空字符串的其他路由器,这个怪癖给我带来了麻烦,我做错了什么,以及如何在无需手动注入变量的情况下仍然成功运行测试?以及:这个问题会转化为生产吗?


解决方案


我的设置是错误的,我在测试中没有使用 *mux.router 而是直接调用处理程序。如果我想使用我的函数 makeapp 返回的 *mux.router 那么我需要使用 net/http/httptest 将其放入测试 http 服务器中。

如果您正在创建请求如果您不进行路由,但仍然需要 vars,那么还有另一种选择。

router := mux.NewRouter()

... // setup your routes

var match mux.RouteMatch
success := router.Match(req, &match)
if success {
  id := match.Vars["id"]
  ...
}

这在准备变量方面与 router.servehttp(req, res) 等效,只是它实际上并不执行处理程序。 match 对象还包含有关请求将到达的路由的更多信息。

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注编程网公众号,一起学习编程~

您可能感兴趣的文档:

--结束END--

本文标题: 测试中 mux.Vars() 返回的是 nil,而不是预期的映射对象

本文链接: https://www.lsjlt.com/news/595778.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作