首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >比较Go单元测试中的两个错误

比较Go单元测试中的两个错误
EN

Stack Overflow用户
提问于 2021-04-28 09:44:45
回答 2查看 2.1K关注 0票数 7

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

代码语言:javascript
运行
复制
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)
}

上述代码的输出是:

代码语言:javascript
运行
复制
reflect:  true
compare:  false
errorIs:  false

我想比较两个错误,reflect.DeepEqual(er1, er2)是我应用的第一个方法,这个方法产生了我想要的输出,但是这个方法有来自go lint的警告

代码语言:javascript
运行
复制
avoid using reflect.DeepEqual with errorsdeepequalerrors

在google搜索之后,有些人告诉我一些方法:

cmp.Equal(er1, er2, cmpopts.EquateErrors())

  • Use

  • 使用cmp包进行比较:错误包要比较:errors.Is(er1, er2)

但上述两种方法都不能产生与第一种方法相同的结果(使用reflect.DeepEqual)。如何在没有go lint警告的情况下比较两个错误,并产生类似reflect.DeepEqual Tks的结果

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-28 10:18:05

根据您编写测试的方式,您可能依赖于reflect.DeepEqual()而忽略linter警告;

缺点是:您根据返回的错误的内部结构而开始。

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

  • 大多数情况下,我们只是将错误与nil
  • 进行比较,在某些情况下,我们的函数返回预定义的错误值,并测试这些特定值:

代码语言:javascript
运行
复制
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) { ...

当我们的生产代码要求发现一个特定的错误(一个常见的用例是)时,我们编写的代码忠实地包装了已知的错误,我们使用errors.Is() (在生产代码和测试代码中都使用),在只需要测试的时候使用

  • 来松散地确认一个错误是否匹配某些东西而不是其他什么东西(例如:Parse error而不是File not found),我们只需在错误消息中搜索字符串:

< code >F 218

代码语言:javascript
运行
复制
if err == nil || !strings.Contains(err.Error(), "database name is not exists") {
    t.Errorf("unexpected error : %s", err)
}
票数 3
EN

Stack Overflow用户

发布于 2022-05-26 11:32:09

我发现有用的是使用cmp.Diff和cmpopts.IgnoreFields来忽略引起详细问题的特定错误字段,然后我就用string.Contains或任何我认为合适的方法对错误进行检查。

所以它是这样的:

代码语言:javascript
运行
复制
if diff := cmp.Diff(expected, got, cmpopts.IgnoreFields(expected, "ErrorField")); diff != "" { 
          // found diff not including the error
}

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67297747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档