如何单元测试Go错误

时间:2017-02-04 00:23:45

标签: unit-testing go error-handling

当你是具有error返回类型的单元测试函数时,我想知道如何正确地测试此错误。您是否应该检查错误是否为零?或者您是否应该验证错误字符串是否与期望的字符串匹配?

4 个答案:

答案 0 :(得分:4)

是的我测试我的函数返回错误并检查错误消息是否匹配。但是,您需要检查它还是仅检查错误不是nil

假设您有这样的功能:

func returnSomeErr(input int)error{
    if input > 0{
        return nil
    }
    return errors.New("this is error message")
}

您可以像这样对错误消息进行单元测试:

// testing tot get error message
func TestReturnSomeErr(t *testing.T){
   Expected := "this is error message"
   actual := returnSomeErr(-1)

   if actual.Error() != Expected{
        t.Errorf("Error actual = %v, and Expected = %v.", actual, test.Expected)
   }
}

请注意,我正在使用.Error()函数来获取错误消息,以便我可以将其与字符串进行比较。如果输入数据> 0

,您可以创建另一个测试来测试是否没有错误

答案 1 :(得分:3)

在大多数情况下,您只需检查错误是否为零。

除非绝对必要,否则我建议不要检查错误字符串。我通常认为错误字符串仅供人类使用。

如果您需要有关错误的更多详细信息,一个更好的选择是拥有自定义错误类型。然后你可以切换错误。(类型),看看它是否是你期望的类型。 如果您需要更多详细信息,可以使自定义错误类型包含您可以在测试中检查的值。

Go的错误只是具有Error() string方法的类型的接口,因此自己实现它们很简单。 https://blog.golang.org/error-handling-and-go

答案 2 :(得分:0)

我经常使用这个简单的功能来检查错误:

// ErrorContains checks if the error message in out contains the text in
// want.
//
// This is safe when out is nil. Use an empty string for want if you want to
// test that err is nil.
func ErrorContains(out error, want string) bool {
    if out == nil {
        return want == ""
    }
    if want == "" {
        return false
    }
    return strings.Contains(out.Error(), want)
}

用法示例:

if !ErrorContains(err, "unexpected banana") {
    t.Errorf("unexpected error: %v", err)
}

if !ErrorContains(err, "") {
    t.Errorf("unexpected error: %v", err)
}

我发现这在表驱动测试中特别有用,因为我可以执行以下操作:

tests := struct{
    want    string
    wantErr string
}{
    {
        "some output",
        "",  // No error expected
    },
    {
        "",
        "out of coconuts",
    }
}

它可以避免与nilerrors.New()等类似的事情。

我使用string.Contains()而不是检查完整错误,因为它更可靠。我只想知道这是否大致是我所期望的错误(而不是完全不相关的错误)。我很少检查完整的错误消息,但改用关键字(例如“意外末尾”,“不够”等)


此功能是github.com/teamwork/test程序包的一部分(我是该程序包的主要作者),但是如果我仅使用此功能,而不使用该程序包中的任何其他功能,我通常只会复制/粘贴该功能。

答案 3 :(得分:0)

证词package将派上用场。

在文档中:“ EqualErrorf断言某个函数返回了错误(即不是nil),并且该错误等于所提供的错误。”:

assert.EqualErrorf(t, err, expectedErrorMsg, "Error should be: %v, got: %v", expectedErrorMsg, err)

断言错误消息包含一个子字符串:

assert.Containsf(t, err.Error(), tt.wantErrMsg, "expected error containing %q, got %s", tt.wantErrMsg, err)

t的类型为*testing.T,而err的类型为error