go - 测试从 panic 中恢复

标签 go

我想测试一个构造函数,但如果未提供某些数据,我需要 panic ,如何在测试中从 panic 中恢复?

目前,我已在 TestNew 函数中添加了带有恢复功能的延迟,但如果 map 中的某个元素具有空 URL,则不会检查其余部分。

t.go

package testing

type test {
  url string
}

func New(ops map[string]string) *test {
  if ops["url"] == "" {
    panic("Url missing")
  }
  var t = new(test)
  t.url = ops["url"]
  return t
}

t_test.go

package testing

type testTest map[string]string
var testingTest = []testTest {
  testTest {
    "url": "test",
  },
  testTest{
    "url": "",
  },
}

func NewTest(t *testing.T) {
  defer func() {
    recover()
  }()

  for _, e := range testingTest {
    url := New(e)
    url.hasUrl(t, e["url"])
  }
}

func (s *test) hasUrl(t *testing.T, u string) {
  if s.url != u {
    t.Errorf("Expected %s to be equal with %s", s.url, u)
  }
}

最佳答案

我想说,为依赖panic/recover的库设计API并不是一个正确的方法。 Go 有错误模式,因此如果 New 方法无法测试,它可以返回状态。

package testing

type test {
  url string
}

func New(ops map[string]string) (*test, bool) {
  if ops["url"] == "" {
    return nil, false
  }
  var t = new(test)
  t.url = ops["url"]
  return t, true
}

然后

for _, e := range testingTest {
  url, ok := New(e)
  if ok {
    url.hasUrl(t, e["url"])
  }
}

如果您坚持使用panic,那么您可以将调用包装到函数中并在其中恢复。但是您仍然需要向调用者提供状态。

package main

import "fmt"

func test(e int) {
    if e == 2 {
        panic("panic!")
    }
}

func main() {
    for _, e := range []int{1, 2, 3} {
        func() {
            defer func() { recover() }()
            test(e)
            fmt.Println("testing", e)
        }()
    }
}

关于go - 测试从 panic 中恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31706145/

相关文章:

rest - 在 Go 中将路由注册到中心对象

go - 为什么每次运行程序时 math/rand 包中的 rand.Intn() 函数都会生成相同的随机数序列?

go - GoLang 中使用 channel 的优先级队列

go - 如何永久删除 GORM 中的关联

json - 在golang中编辑继承属性的标签?

loops - 使用 goroutine 无限期地迭代文件

go - http 连接卡在 close_wait 状态

mysql - 为什么这一小段代码需要 11 秒来执行这几个数据库调用?

map - golang map 比较 : partial match

go - 如何在kubernetes中过滤完成的作业