带有错误的表格测试

huangapple go评论158阅读模式
英文:

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

huangapple
  • 本文由 发表于 2017年7月29日 08:02:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/45383927.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定