3 回答
TA贡献1877条经验 获得超1个赞
我会说为依赖于恐慌/恢复的库设计 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)
}()
}
}
TA贡献1804条经验 获得超7个赞
我对问题中的话感到困惑,但我认为它始于我同样的担忧。您已经定义了一个在违反前提条件时发生恐慌的函数,而不是替代方法(返回错误、使用默认值、什么都不做……);就像为数组做出的合理选择一样:
var a [1]int
a[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。
- 3 回答
- 0 关注
- 193 浏览
添加回答
举报