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

假设我有一个函数,它返回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?


HUX布斯
浏览 128回答 3
3回答

天涯尽头无女友

该os软件包提供了os.IsNotExist检查各种文件存在错误的功能:if err != nil && os.IsNotExist(err) {    fmt.Println("file doesn't exist")}

慕娘9325324

在更一般的级别上,您可以使用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,因此您可以快速轻松地测试查询返回的错误是否表明没有结果行。

慕神8447489

您可以创建一个“常量”并将其用作比较的参考,如下所示: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)    }}
打开App,查看更多内容
随时随地看视频慕课网APP