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

仅使用 golang 中的标准库断言特定错误

仅使用 golang 中的标准库断言特定错误

Go
HUX布斯 2022-01-17 11:01:07
假设我有一个函数,它返回base64位于特定path.func getFile(path string) (string, error) {    imgFile, err := ioutil.ReadFile(path)    if err != nil {        return "", fmt.Errorf("Error opening image file: %s", err)    }    base64 := base64.StdEncoding.EncodeToString(imgFile)    return base64, nil}现在,我正在为这个函数编写表驱动测试,它们现在看起来像这样。func TestGetFile(t *testing.T) {    type getFileTest struct {        Path   string        Base64 string        Err    error    }    getFileTests := []getFileTest{        {"", "", nil},    }    for _, td := range getFileTests {        base64, err := getFile(td.Path)        if err != nil {            t.Errorf("TestGetFile: Error calling getFile: %s", err)        }        if base64 != td.Base64 {            t.Errorf("TestGetFile: Return values from getFile is not expected: Expected: %s, Returned: %s", td.Base64, base64)        }    }}现在,当前测试失败:-test.go:18: TestGetFile: Error calling getFile: Error opening image file: open : no such file or directory当我将空路径传递给时,如何断言我得到了正确的错误getFile?
查看完整描述

3 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

该os软件包提供了os.IsNotExist检查各种文件存在错误的功能:


if err != nil && os.IsNotExist(err) {

    fmt.Println("file doesn't exist")

}


查看完整回答
反对 回复 2022-01-17
?
慕娘9325324

TA贡献1783条经验 获得超4个赞

在更一般的级别上,您可以使用strings.Contains()调用err.Error()(返回错误消息的字符串)。例子:


if err == nil || !strings.Contains(err.Error(), "no such file or directory") {

    // we didn't get the error we were expecting

}

但是请注意,字符串匹配相当脆弱。如果包作者更改了错误消息,您的测试可能会开始失败,尽管仍然返回正确的错误。


这就是为什么 Go 中的习惯用法通常是让包将它们返回的错误类型定义为包级常量,或者更常见的是变量,因为fmt.Errorf()并errors.New()返回error接口类型,根据定义,接口类型不能是常量,因为接口是引用类型. 作为包级常量,可以直接对其进行测试。例如,sql包定义了sql.ErrNoRows,因此您可以快速轻松地测试查询返回的错误是否表明没有结果行。


查看完整回答
反对 回复 2022-01-17
?
慕神8447489

TA贡献1780条经验 获得超1个赞

您可以创建一个“常量”并将其用作比较的参考,如下所示:


var ErrFile = errors.New("Error opening image file")


func getFile(path string) (string, error) {

    return "", ErrFile

}


func main() {

    f := "problem.txt"

    _, err := getFile(f)

    if err == ErrFile {

       fmt.Printf("Problem with file %s", f)

    }

}

或者,如果您需要更大的灵活性,您可以创建自己的错误类型。


type FileError struct {

    Path string

}


func (e *FileError) Error() string {

    return fmt.Sprintf("Error opening image file: %s", e.Path)

}


func getFile(path string) (string, error) {

    return "", &FileError{Path: path}

}


func main() {

    f := "problem.txt"

    _, err := getFile(f)

    if ferr, ok := err.(* FileError); ok {

        fmt.Println(ferr)

    }

}


查看完整回答
反对 回复 2022-01-17
  • 3 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

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