带有错误的表格测试

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

Table tests with errors

问题

给定一个类似这样的 Golang 函数:

  1. func GetKey(key string, data map[string]string) (string, error) {
  2. value, present := data[key]
  3. if !present {
  4. return "", errors.New(fmt.Sprintf("requested key does not exist: %s", key))
  5. }
  6. return value, nil
  7. }

我该如何使用测试表格来测试返回的错误是否存在?例如:

  1. func TestGetKey(t *testing.T) {
  2. cases := []struct {
  3. Input map[string]string
  4. Key string
  5. Result string
  6. Err error
  7. }{
  8. {
  9. map[string]string{
  10. "foo": "bar",
  11. "baz": "bah",
  12. },
  13. "foo",
  14. "bar",
  15. nil,
  16. },
  17. {
  18. map[string]string{
  19. "foo": "bar",
  20. "baz": "bah",
  21. },
  22. "nope",
  23. "",
  24. ????, // 这里应该填什么?
  25. },
  26. }
  27. // 还有类似这样的代码
  28. for _, v := range cases {
  29. actual, err := GetKey(v.Key, v.Input)
  30. if actual != v.Result {
  31. t.Fatalf("Expected %s. Got %s", v.Result, actual)
  32. }
  33. }
  34. }

你想知道在第二个测试用例中,应该填写什么来测试返回的错误是否存在。

英文:

given a Golang function like this:

  1. func GetKey(key string, data map[string]string) (string, error) {
  2. value, present := data[key]
  3. if !present {
  4. return "", errors.New(fmt.Sprintf("requested key does not exist: %s", key))
  5. }
  6. return value, nil
  7. }

how would i go about testing the presence of the error I return, using Test Tables? For example:

  1. func TestGetKey(t *testing.T) {
  2. cases := []struct {
  3. Input map[string]string
  4. Key string
  5. Result string
  6. Err error
  7. }{
  8. {
  9. map[string]string{
  10. "foo": "bar",
  11. "baz": "bah",
  12. },
  13. "foo",
  14. "bar",
  15. nil,
  16. },
  17. {
  18. map[string]string{
  19. "foo": "bar",
  20. "baz": "bah",
  21. },
  22. "nope",
  23. "",
  24. ????,
  25. },
  26. }
  27. // and something like
  28. for _, v := range cases {
  29. actual, err := GetKey(v.Key, v.Input)
  30. if actual != v.Result {
  31. t.Fatalf("Expected %s. Got %s", v.Result, actual)
  32. }
  33. }
  34. }

答案1

得分: 1

你可以存储你期望得到的相同错误,并断言两者返回的是相同的 Error()

所以在你的映射中,对于错误情况:

  1. {
  2. map[string]string{
  3. "foo": "bar",
  4. "baz": "bah",
  5. },
  6. "nope",
  7. "",
  8. errors.New("requested key does not exist: nope"),
  9. }

在你的测试代码中:

  1. for _, v := range cases {
  2. actual, err := GetKey(v.Key, v.Input)
  3. if actual != v.Result {
  4. t.Fatalf("Expected %s. Got %s", v.Result, actual)
  5. }
  6. if (v.Err != nil) && (err == nil) {
  7. t.Fatalf("Expecting error (%s), did not get it", v.Err.Error())
  8. } else if (v.Err == nil) && (err != nil) {
  9. t.Fatalf("Got unexpected error: (%s)", err.Error())
  10. } else if (v.Err != nil) && (err != nil) && (v.Err.Error() != err.Error()) {
  11. t.Fatalf("Expecting error (%s). Got (%s)", v.Err.Error(), err.Error())
  12. }
  13. }

请注意,有几种情况下你不期望出现错误,但实际上却出现了错误,期望出现错误但没有出现,以及期望出现错误但出现了不同的错误。

英文:

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:

  1. {
  2. map[string]string{
  3. "foo": "bar",
  4. "baz": "bah",
  5. },
  6. "nope",
  7. "",
  8. errors.New("requested key does not exist: nope"),
  9. }

And in your test code:

  1. for _, v := range cases {
  2. actual, err := GetKey(v.Key, v.Input)
  3. if actual != v.Result {
  4. t.Fatalf("Expected %s. Got %s", v.Result, actual)
  5. }
  6. if (v.Err != nil) && (err == nil) {
  7. t.Fatalf("Expecting error (%s), did not get it", v.Err.Error())
  8. } else if (v.Err == nil) && (err != nil) {
  9. t.Fatalf("Got unexpected error: (%s)", err.Error())
  10. } else if (v.Err != nil) && (err != nil) && (v.Err.Error() != err.Error()) {
  11. t.Fatalf("Expecting error (%s). Got (%s)", v.Err.Error(), err.Error())
  12. }
  13. }

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

也许我没有看到什么,但通常我是这样做的:

  1. actual, err := GetKey(v.Key)
  2. if err != v.Err {
  3. t.Errorf("意外错误:%s", err)
  4. }

或者,如果返回的错误可能不是特定的已知错误值,我可能会将其转换为字符串:

  1. actual, err := GetKey(v.Key)
  2. var errMsg string
  3. if err != nil {
  4. errMsg = err.Error()
  5. }
  6. if errMsg != v.errMsg {
  7. t.Errorf("意外错误:%s", errMsg)
  8. }
英文:

Maybe I'm not seeing something, but this is usually how I do it:

  1. actual, err := GetKey(v.Key)
  2. if err != v.Err {
  3. t.Errorf("Unexpected error: %s", err)
  4. }

Or, if the returned error might not be a specific known error value, I might flatten to a string:

  1. actual, err := GetKey(v.Key)
  2. var errMsg string
  3. if err != nil {
  4. errMsg = err.Error()
  5. }
  6. if errMsg != v.errMsg {
  7. t.Errorf("Unexpected error: %s", errMsg)
  8. }

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:

确定