Golang中使用Testify和Echo时遇到上下文转换错误问题

Golang中使用Testify和Echo时遇到上下文转换错误问题 我使用 Echo 创建了 API,并想用 Testify 进行测试,但当我尝试运行时,它不允许我这样做。下面我粘贴了我的代码,如果我做错了什么,请纠正我。

要测试的 API

type WebContext struct {
    echo.Context
    Registry
    sess *sessions.Session
}
func GetWebContext(c echo.Context) *WebContext {
    return c.(*WebContext)
}
func EmailTemplateDelete(c echo.Context) error {
    wc  := core.GetWebContext(c)
    r := model.NewSuccessResponse()

    u, err := service.GetUserForRequest(wc)
    if err != nil {
        return wc.JSON(http.StatusUnauthorized, model.NewErrorResponse("error in fetching user details"))
    }
    return c.JSON(http.StatusOK, r)
}

我用于 Testify 的代码

func TestEmailTemplateDelete(t *testing.T) {
    // Setup
    e := echo.New()
    req := httptest.NewRequest(http.MethodGet, "/", nil)
    rec := httptest.NewRecorder()
    c := e.NewContext(req, rec)
    c.SetPath("/api/v1/emai_template")
    if assert.NoError(t, EmailTemplateDelete(c)) {
        assert.Equal(t, http.StatusOK, rec.Code)
        //assert.Equal(t, userJSON, strings.TrimSpace(rec.Body.String()))
    }
}

当我执行 go test email_template.go email_template_test.go 时,它抛出了一个错误:

--- FAIL: TestEmailTemplateDelete (0.00s)
panic: interface conversion: echo.Context is *echo.context, not *core.WebContext [recovered]
panic: interface conversion: echo.Context is *echo.context, not *core.WebContext

如果我犯了任何愚蠢的错误,请纠正我,因为我是 Golang 新手。

提前感谢


更多关于Golang中使用Testify和Echo时遇到上下文转换错误问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

非常感谢阿里,这对我很有用 🙂

更多关于Golang中使用Testify和Echo时遇到上下文转换错误问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢Ali的回复,您是否知道我们该如何实现呢?我的意思是,我们如何为使用echo上下文的API编写单元测试?

希望这能有所帮助: 将这段代码

func GetWebContext(c echo.Context) *WebContext {
return c.(*WebContext)
}

替换为:

func GetWebContext(c echo.Context) *WebContext {
return &WebContext{Context:c}
}

无法将内嵌类型转换为父类型。

问题在于你的测试代码创建了一个标准的 echo.Context,但在 EmailTemplateDelete 函数中,你尝试通过 core.GetWebContext(c) 将其转换为 *WebContext。由于测试中创建的上下文不是 *WebContext 类型,因此类型断言失败。

要解决这个问题,你需要在测试中创建一个 *WebContext 实例,而不是标准的 echo.Context。以下是修改后的测试代码:

func TestEmailTemplateDelete(t *testing.T) {
    // Setup
    e := echo.New()
    req := httptest.NewRequest(http.MethodGet, "/", nil)
    rec := httptest.NewRecorder()
    
    // 创建标准 echo.Context
    echoCtx := e.NewContext(req, rec)
    echoCtx.SetPath("/api/v1/emai_template")
    
    // 创建 WebContext 包装标准上下文
    wc := &core.WebContext{
        Context: echoCtx,
        // 初始化其他字段
        Registry: nil, // 根据实际情况初始化
        sess:     nil, // 根据实际情况初始化
    }
    
    // 使用 WebContext 进行测试
    if assert.NoError(t, EmailTemplateDelete(wc)) {
        assert.Equal(t, http.StatusOK, rec.Code)
    }
}

如果你的 WebContext 需要特定的初始化逻辑,可以创建一个辅助函数:

func NewTestWebContext(e *echo.Echo, req *http.Request, rec *httptest.ResponseRecorder) *core.WebContext {
    echoCtx := e.NewContext(req, rec)
    return &core.WebContext{
        Context:  echoCtx,
        Registry: nil, // 测试用的模拟 Registry
        sess:     nil, // 测试用的模拟 Session
    }
}

然后在测试中使用:

func TestEmailTemplateDelete(t *testing.T) {
    e := echo.New()
    req := httptest.NewRequest(http.MethodGet, "/", nil)
    rec := httptest.NewRecorder()
    
    wc := NewTestWebContext(e, req, rec)
    wc.SetPath("/api/v1/emai_template")
    
    if assert.NoError(t, EmailTemplateDelete(wc)) {
        assert.Equal(t, http.StatusOK, rec.Code)
    }
}

这样就能避免类型转换错误,因为传递给 EmailTemplateDelete 函数的已经是 *WebContext 类型,而不是需要转换的标准 echo.Context

回到顶部