当你是具有error
返回类型的单元测试函数时,我想知道如何正确地测试此错误。您是否应该检查错误是否为零?或者您是否应该验证错误字符串是否与期望的字符串匹配?
答案 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",
}
}
它可以避免与nil
,errors.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