gpt4 book ai didi

go - 如何模拟 gin.Context?

转载 作者:行者123 更新时间:2023-12-04 07:40:18 26 4
gpt4 key购买 nike

嗨,我一直在尝试模拟 gin.Context 但我无法让它工作
我正在尝试他们在 solution 中所做的事情但它不适用于我的路由器这是我遇到的错误r.POST("/urls", urlRepo.CreateUrl)cannot use urlRepo.CreateUrl (value of type func(c controllers.Icontext)) as gin.HandlerFunc value in argument to r.POSTcompilerIncompatibleAssign这是我为稍后模拟而创建的接口(interface)以及我将在其中进行测试的方法

type Icontext interface {
BindJSON(obj interface{}) error
JSON(code int, obj interface{})
AbortWithStatus(code int)
AbortWithStatusJSON(code int, jsonObj interface{})
}
func (repository *UrlRepo) CreateUrl(c Icontext) {
var url models.Url
c.BindJSON(&url)
if !validators.IsCreateJsonCorrect(url) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Error format in Short or Full"})
return
}
err := repository.reposito.CreateUrl(repository.Db, &url)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err})
return
}
c.JSON(http.StatusOK, url)
}
代替
func (repository *UrlRepo) CreateUrl(c Icontext)
它是
func (repository *UrlRepo) CreateUrl(c *gin.Context) 

最佳答案

严格来说,你不能“ mock ”一个 *gin.Context以一种有意义的方式,因为它是 struct带有未导出的字段和方法。
此外,您不能传递给 r.POST()类型不是 gin.HandlerFunc 的函数, 定义为 func(*gin.Context) .您的处理程序的类型 CreateUrl(c Icontext)根本不匹配。
如果您的目标是对 Gin 处理程序进行单元测试,那么您绝对不必模拟 *gin.Context .您应该做的是在其中设置测试值。为此,您可以简单地使用 gin.CreateTestContext()并手动初始化其中一些字段。更多信息 here .
如果出于其他原因,您的目标是提供 *gin.Context 功能的替代实现。为了在您的处理程序中使用,您可以做的是使用您自己的替代方法定义您自己的类型并嵌入 *gin.Context在里面。
在实践中:

type MyGinContext struct {
*gin.Context
}

func (m *MyGinContext) BindJSON(obj interface{}) error {
fmt.Println("my own BindJSON")
return m.Context.BindJSON(obj) // or entirely alternative implementation
}

// Using the appropriate function signature now
func (repository *UrlRepo) CreateUrl(c *gin.Context) {
myCtx := &MyGinContext{c}

var url models.Url
_ = myCtx.BindJSON(&url) // will also print "my own BindJSON"
// ...

// other gin.Context methods are promoted and available on MyGinContext
myCtx.Status(200)
}
但老实说,我不确定您为什么要覆盖 *gin.Context 的某些方法。 .如果你想提供不同的绑定(bind)逻辑,甚至不同的渲染,你可以实现库已经暴露的接口(interface)。例如:
实现绑定(bind): c.ShouldBindWith()将接口(interface) binding.Binding 作为第二个参数您可以实现:
type MyBinder struct {
}

func (m *MyBinder) Name() string {
return "foo"
}

func (m *MyBinder) Bind(*http.Request, interface{}) error {
// stuff
return nil
}

func MyHandler(c *gin.Context) {
var foo struct{/*fields*/}
c.ShouldBindWith(&foo, &MyBinder{})
}
实现一个渲染器:
type MyRenderer struct {
}

type Render interface {
func (m *MyRenderer) Render(http.ResponseWriter) error {
// ...
return nil
}

func (m *MyRenderer) WriteContentType(w http.ResponseWriter) {
header := w.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = "application/foo+bar"
}
}

func MyHandler(c *gin.Context) {
c.Render(200, &MyRenderer{})
}

关于go - 如何模拟 gin.Context?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67508787/

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