英文:
Table tests with errors
问题
给定一个类似这样的 Golang 函数:
func GetKey(key string, data map[string]string) (string, error) {
value, present := data[key]
if !present {
return "", errors.New(fmt.Sprintf("requested key does not exist: %s", key))
}
return value, nil
}
我该如何使用测试表格来测试返回的错误是否存在?例如:
func TestGetKey(t *testing.T) {
cases := []struct {
Input map[string]string
Key string
Result string
Err error
}{
{
map[string]string{
"foo": "bar",
"baz": "bah",
},
"foo",
"bar",
nil,
},
{
map[string]string{
"foo": "bar",
"baz": "bah",
},
"nope",
"",
????, // 这里应该填什么?
},
}
// 还有类似这样的代码
for _, v := range cases {
actual, err := GetKey(v.Key, v.Input)
if actual != v.Result {
t.Fatalf("Expected %s. Got %s", v.Result, actual)
}
}
}
你想知道在第二个测试用例中,应该填写什么来测试返回的错误是否存在。
英文:
given a Golang function like this:
func GetKey(key string, data map[string]string) (string, error) {
value, present := data[key]
if !present {
return "", errors.New(fmt.Sprintf("requested key does not exist: %s", key))
}
return value, nil
}
how would i go about testing the presence of the error I return, using Test Tables? For example:
func TestGetKey(t *testing.T) {
cases := []struct {
Input map[string]string
Key string
Result string
Err error
}{
{
map[string]string{
"foo": "bar",
"baz": "bah",
},
"foo",
"bar",
nil,
},
{
map[string]string{
"foo": "bar",
"baz": "bah",
},
"nope",
"",
????,
},
}
// and something like
for _, v := range cases {
actual, err := GetKey(v.Key, v.Input)
if actual != v.Result {
t.Fatalf("Expected %s. Got %s", v.Result, actual)
}
}
}
答案1
得分: 1
你可以存储你期望得到的相同错误,并断言两者返回的是相同的 Error()
。
所以在你的映射中,对于错误情况:
{
map[string]string{
"foo": "bar",
"baz": "bah",
},
"nope",
"",
errors.New("requested key does not exist: nope"),
}
在你的测试代码中:
for _, v := range cases {
actual, err := GetKey(v.Key, v.Input)
if actual != v.Result {
t.Fatalf("Expected %s. Got %s", v.Result, actual)
}
if (v.Err != nil) && (err == nil) {
t.Fatalf("Expecting error (%s), did not get it", v.Err.Error())
} else if (v.Err == nil) && (err != nil) {
t.Fatalf("Got unexpected error: (%s)", err.Error())
} else if (v.Err != nil) && (err != nil) && (v.Err.Error() != err.Error()) {
t.Fatalf("Expecting error (%s). Got (%s)", v.Err.Error(), err.Error())
}
}
请注意,有几种情况下你不期望出现错误,但实际上却出现了错误,期望出现错误但没有出现,以及期望出现错误但出现了不同的错误。
英文:
You could store the same error you are expecting to get and then assert that both return the same Error()
.
So in your map, for the error case:
{
map[string]string{
"foo": "bar",
"baz": "bah",
},
"nope",
"",
errors.New("requested key does not exist: nope"),
}
And in your test code:
for _, v := range cases {
actual, err := GetKey(v.Key, v.Input)
if actual != v.Result {
t.Fatalf("Expected %s. Got %s", v.Result, actual)
}
if (v.Err != nil) && (err == nil) {
t.Fatalf("Expecting error (%s), did not get it", v.Err.Error())
} else if (v.Err == nil) && (err != nil) {
t.Fatalf("Got unexpected error: (%s)", err.Error())
} else if (v.Err != nil) && (err != nil) && (v.Err.Error() != err.Error()) {
t.Fatalf("Expecting error (%s). Got (%s)", v.Err.Error(), err.Error())
}
}
Note that there are several cases for when you don't expected an error but actually got one, expected one and did not get it, and expected one and got a different one.
答案2
得分: 0
也许我没有看到什么,但通常我是这样做的:
actual, err := GetKey(v.Key)
if err != v.Err {
t.Errorf("意外错误:%s", err)
}
或者,如果返回的错误可能不是特定的已知错误值,我可能会将其转换为字符串:
actual, err := GetKey(v.Key)
var errMsg string
if err != nil {
errMsg = err.Error()
}
if errMsg != v.errMsg {
t.Errorf("意外错误:%s", errMsg)
}
英文:
Maybe I'm not seeing something, but this is usually how I do it:
actual, err := GetKey(v.Key)
if err != v.Err {
t.Errorf("Unexpected error: %s", err)
}
Or, if the returned error might not be a specific known error value, I might flatten to a string:
actual, err := GetKey(v.Key)
var errMsg string
if err != nil {
errMsg = err.Error()
}
if errMsg != v.errMsg {
t.Errorf("Unexpected error: %s", errMsg)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论