unit-testing - 测试非不透明错误值

标签 unit-testing testing go

在 Go 中是否有比较非不透明错误值的最佳实践?

大多数代码库似乎将错误视为不透明的(操作成功或失败,无法看到有关导致错误的内部细节)。

这使得编写单元测试变得容易,因为您需要做的就是根据预期错误断言实际错误。除此之外,我见过人们做的最多的事情就是比较错误字符串以确保它至少包含一些关键信息。例如:

if err == nil || !strings.Contains(err.Error(), "not found in the Raft configuration") {
  t.Fatalf("err: %v", err)
}

但是对于需要额外错误信息的情况(比如在表单验证中,您需要指定无效的字段名称、值、错误代码以及可能的一些嵌套错误),您会怎么做?

我不能简单地执行 reflect.DeepEqual(),因为错误将包含一个唯一的堆栈跟踪,这将使比较每次都失败。此外,嵌套错误会使测试逻辑更加复杂,您将需要各种容易出错的逻辑(循环、递归)来比较所需的字段。是否有测试这种性质的错误的标准方法?

最佳答案

虽然这可能无法回答您有关检查未正确完成的错误的问题,但这里至少是一个示例,说明如何以正确的方式创建和使用错误。

标准库包中通常做的是将错误创建为导出变量,然后可以抛出这些错误并进行比较。这是一个示例……无论它多么缺乏想象力。

https://play.golang.org/p/JlpguFn2NX

package main

import (
    "errors"
    "fmt"
)

var ErrBadIdea = errors.New("that was dumb")
var ErrNoValue = errors.New("not a real value")

func DoSomething(i int) error {
    if i == 0 {
        return ErrNoValue
    }
    if i < 0 {
        return ErrBadIdea
    }
    // does something that doesn't like negative or zero values
    return nil
}

func main() {
    err := DoSomething(-1)
    fmt.Println(err == ErrBadIdea, err)
    err = DoSomething(0)
    fmt.Println(err == ErrNoValue, err)
}

标准库的 database/sql 包就是一个很好的例子。

https://godoc.org/database/sql#pkg-variables

这些变量存在所以你可以这样测试

if err == sql.ErrNoRows { // these are not the rows you are looking for }

越来越好!

因为error 是一个接口(interface),所以您所要做的就是实现它。这只需要您有一个 func Error() string。请参阅以下示例并惊叹于 interface 的强大功能。

https://play.golang.org/p/3RFrxKGkdm

另请阅读以下有关错误的博客。

https://blog.golang.org/error-handling-and-go

关于unit-testing - 测试非不透明错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43214776/

相关文章:

java - 模拟服务器简单模拟不在体内使用 XML

C# 测试运行配置(*.runsettings)

javascript - RSA Javascript加密和Golang解密

go - 为什么 time.In() 不能在时区 America/New_York 中得到正确的时间

javascript - 多客户端 Node.js 应用程序的 mocha-casperjs headless 测试

java - 在包含远程数据库的 Oracle 上测试 SQL 查询

ruby-on-rails - RSPec 和 Rails 3 的 Mising 模板错误

format - fmt.Sprintf 传递参数数组

visual-studio - 单元测试 : how to access a text file?

unit-testing - Golang单元测试: error conditions