You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang单元测试报错:Expected nil, but got: "null\n" 原因排查

问题原因分析:Expected nil, but got: "null\n"

核心原因

Echo框架的e.JSON()方法在接收nil作为响应体时,会自动将其序列化为JSON标准的null,并且默认在响应末尾添加换行符\n,所以实际响应体内容是字符串"null\n"。而你的测试用assert.Nil(t, rec.Body.String())是在判断字符串是否为Go语言的nil——但rec.Body.String()返回的始终是字符串类型(哪怕是空字符串),字符串变量永远不可能是nil,这才导致了测试断言失败。

代码问题拆解

1. Handler的JSON响应逻辑

Handler最后一行return e.JSON(http.StatusCreated, nil)触发了Echo的JSON序列化规则:将Go的nil转为JSON的null,并自动追加换行符,最终响应体就是null\n。

2. 测试断言的错误用法

rec.Body.String()返回的是string类型,Go语言中字符串类型变量不存在nil状态,只有字符串指针才可能为nil。你用assert.Nil断言字符串本身,逻辑从一开始就不成立。

修复方案

根据业务需求,可选择以下两种修复方式:

方式一:匹配实际响应体

如果业务逻辑确实需要返回null响应,直接修改断言匹配实际结果:

assert.Equal(t, "null\n", rec.Body.String())

方式二:调整Handler的响应输出

如果不需要返回null,可以改为返回空响应或空JSON对象:

  • 返回空响应(推荐用于创建成功无返回数据的场景):
    // Handler代码修改
    return e.NoContent(http.StatusCreated)
    
    对应测试断言:
    assert.Empty(t, rec.Body.String())
    
  • 返回空JSON对象:
    // Handler代码修改
    return e.JSON(http.StatusCreated, map[string]interface{}{})
    
    对应测试断言:
    assert.Equal(t, "{}\n", rec.Body.String())
    

额外的Handler逻辑修复

你的Handler还存在一个隐藏bug:解码错误或服务调用错误时,调用e.JSON()后没有终止后续代码执行,可能导致多次发送响应。正确写法如下:

func (u *userHandler) Create(e echo.Context) error {
    var user User
    err := json.NewDecoder(e.Request().Body).Decode(&user)
    if err != nil {
        return e.JSON(http.StatusUnprocessableEntity, err) // 错误时直接return,终止后续执行
    }
    err = u.userService.Create(user) // 接收Create方法返回的错误
    if err != nil {
        return e.JSON(http.StatusBadRequest, err) // 错误时直接return
    }
    return e.JSON(http.StatusCreated, nil)
}

内容的提问来源于stack exchange,提问作者Fatih

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:52:29