测试从恐慌中恢复

我想测试一个构造函数,但如果没有提供一些数据,我需要恐慌,我如何在测试中从恐慌中恢复过来?


目前我已经在我的 TestNew func 中添加了一个带有恢复的延迟,但如果我的地图中的元素具有空 URL,则不会检查其余元素。



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)

  }

}



慕神8447489
浏览 194回答 3
3回答

冉冉说

我会说为依赖于恐慌/恢复的库设计 API 不是正确的方法。Go 有错误模式,所以如果 New 方法无法测试,它可以返回状态。package testingtype 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 mainimport "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)        }()    }}

三国纷争

我对问题中的话感到困惑,但我认为它始于我同样的担忧。您已经定义了一个在违反前提条件时发生恐慌的函数,而不是替代方法(返回错误、使用默认值、什么都不做……);就像为数组做出的合理选择一样:var a [1]inta[1] = 0 // panic有时您想编写一个测试来证明违反前提条件会导致恐慌并且不会被掩盖。前面的答案还不是很完整,所以这就是我所得到的:func GreatBigFunction(url string) {    if url == "" {        panic("panic!")    }}func main() {    var tests = []struct {        url       string        completes bool    }{        {"a", true},        {"", false},        {"b", true},        {"c", false}, // wrong expectation        {"", true},   // wrong expectation    }    for _, test := range tests {        fmt.Printf("testing that \"%s\" %s\n", test.url, map[bool]string{false: "panics", true: "completes"}[test.completes])        func() {            if !test.completes {                defer func() {                    p := recover()                    if p == nil {                        fmt.Println("t.Fail: should have panicked")                    }                }()            }            GreatBigFunction(test.url)        }()    }    fmt.Println("Bye")}如果测试用例表明函数不应该恐慌,最后一个测试用例检查正常的恐慌处理是否有效。相同的代码在 Playground 上。也可以忽略 的返回值recover但仍然可靠地报告丢失的panic。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go