比较Go for unit test中的2个错误

比较Go for unit test中的2个错误,go,Go,我遇到了如下问题:在编写单元测试时比较两个错误 package main import ( "errors" "fmt" "reflect" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" ) func main() { er1 := error

我遇到了如下问题:在编写单元测试时比较两个错误

package main

import (
    "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:  true
compare:  false
errorIs:  false
我想比较2个错误和
反射。DeepEqual(er1,er2)
是我应用的第一种方法,该方法产生我想要的输出,但该方法有一个来自
go lint
的警告:

avoid using reflect.DeepEqual with errorsdeepequalerrors
在谷歌搜索之后,一些人告诉我一些方法:

  • 使用cmp包比较:
    cmp.Equal(er1、er2、cmpopts.equalizeErrors())
  • 使用错误包进行比较:
    errors.Is(er1,er2)
但上述两种方法不能产生与第一种方法相同的结果(使用reflect.DeepEqual)。 如何在没有警告的情况下比较来自
go lint
的两个错误,并生成类似
reflect.DeepEqual

Tks

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


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

  • 大多数时候,我们只是将错误与
    nil
    进行比较
  • 在某些情况下,我们的函数返回预定义的错误值,并测试这些特定值:
  • 当我们的生产代码要求发现特定错误时(常见的用例是
    io.EOF
    ),我们编写的代码尽职尽责地包装了已知错误,我们使用
    errors.is()
    (在生产代码和测试代码中)
  • 当仅在测试中需要松散地确认某个错误与某个错误匹配,而不是其他错误(例如:
    Parse error
    和not
    File not found
    )时,我们只需在错误消息中搜索字符串:

如果你需要一种方法使“两个不同的错误看起来相等”,那么你可能做错了什么,你用错误的方式处理错误。您应该使用
errors.Is()
,如果报告为false,则应将这些错误视为不同的错误。许多地方标准库返回错误,您可以使用
=
运算符将这些错误与导出变量中存储的值进行比较,例如
io.EOF
csv.ErrFieldCount
。您不需要比这更复杂的逻辑。@ThoQuach:您打算比较单元测试代码中的错误吗?或者在你的应用程序代码中?@LeGEC,没错,我需要比较一下Golang单元测试中的两个错误
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) { ...
if err == nil || !strings.Contains(err.Error(), "database name is not exists") {
    t.Errorf("unexpected error : %s", err)
}