仅使用golang中的标准库来声明特定错误

时间:2016-06-06 13:48:12

标签: unit-testing testing go

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

答案 0 :(得分:2)

$programs_and_employees = str_replace("\n", "<w:br/>", $programs_and_employees); 包提供os.IsNotExist函数来检查各种文件存在错误:

os

答案 1 :(得分:1)

在更一般的级别上,您可以在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()返回{{1}接口类型,根据定义,它不能是常量,因为接口是引用类型。作为包级常量,可以直接测试它们。例如,error包定义了sql,因此您可以快速轻松地测试返回的查询是否表明没有结果行。

答案 2 :(得分:0)

您可以创建一个“常量”并将其用作比较参考:

System.Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(Globals.ThisAddIn.Application.ActiveDocument.Content.get_XML()));

Test on playground

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

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)
    }
}

Test on playground