为了账号安全,请及时绑定邮箱和手机立即绑定

在单元测试中比较 Go 中的 2 个错误

在单元测试中比较 Go 中的 2 个错误

Go
慕丝7291255 2022-08-24 20:16:06
我遇到了如下问题:编写单元测试时比较2个错误package mainimport (    "errors"    "fmt"    "reflect"        "github.com/google/go-cmp/cmp"    "github.com/google/go-cmp/cmp/cmpopts")func main() {    er1 := errors.New("database name is not exists")    er2 := errors.New("database name is not exists")        result1 := reflect.DeepEqual(er1, er2)    fmt.Println("reflect: ", result1)        result2 := cmp.Equal(er1, er2, cmpopts.EquateErrors())    fmt.Println("compare: ", result2)        result3 := errors.Is(er1, er2)    fmt.Println("errorIs: ", result3)}以上代码的输出是:reflect:  truecompare:  falseerrorIs:  false我想比较2错误,这是我应用的第一种方法,这种方法产生我想要的输出,但这种方法有一个警告:reflect.DeepEqual(er1, er2)go lintavoid using reflect.DeepEqual with errorsdeepequalerrors在谷歌搜索之后,有些人告诉我一些方法:使用 cmp 包比较:cmp.Equal(er1, er2, cmpopts.EquateErrors())使用错误包进行比较:errors.Is(er1, er2)但上述两种方法都不能产生与第一种方法相同的结果(使用反射。深度等式)。我如何在没有警告的情况下比较2个错误并产生像Tks一样的结果go lintreflect.DeepEqual
查看完整描述

2 回答

?
偶然的你

TA贡献1841条经验 获得超3个赞

根据您编写测试的方式,您可能会依赖并忽略 linter 警告 ;
缺点是:您根据返回的错误的内部结构开始。reflect.DeepEqual()


在我阅读的测试代码和我们编写的测试代码中,我们使用以下模式之一:

  • 大多数时候,我们只是将错误与nil ;

  • 在某些情况下,我们的函数返回预定义的错误值,并测试这些特定值:

package pkg


var ErrUnboltedGizmo = errors.New("gizmo is unbolted")


// in test functions, depending on the case :

if err == pkg.ErrUnboltedGizmo { ...

// or :

if errors.Is(err, pkg.ErrUnboltedGizmo) { ...

当我们的生产代码要求发现特定错误时(一个常见的用例是),我们编写代码来尽职尽责地包装该已知错误,并且我们使用(在生产代码和测试代码中),io.EOFerrors.Is()

当需要仅在测试中松散地确认错误与某些内容匹配而不是其他内容(例如:而不是)时,我们只需在错误消息中搜索字符串:Parse errorFile not found

if err == nil || !strings.Contains(err.Error(), "database name is not exists") {

    t.Errorf("unexpected error : %s", err)

}


查看完整回答
反对 回复 2022-08-24
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

我发现有用的是使用cmp。与 cmpopts 比较。IgnoreFields忽略导致问题的单独错误字段,然后我只是用字符串对错误运行检查。包含或我认为合适的任何东西。

所以它是这样的:

if diff := cmp.Diff(expected, got, cmpopts.IgnoreFields(expected, "ErrorField")); diff != "" { 
          // found diff not including the error
          }

现在只检查自己的错误,仅此而已。

是的,我知道你已经标记了一个解决方案,但也许它会帮助某人:)


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信