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
相关产品推荐
相关产品推荐

