为了账号安全,请及时绑定邮箱和手机立即绑定

如何测试恐慌?

如何测试恐慌?

Go
慕的地8271018 2021-10-25 16:28:04
我目前正在考虑如何编写测试来检查给定的代码片段是否出现恐慌?我知道 Go 用于recover捕获恐慌,但与 Java 代码不同,您无法真正指定在出现恐慌时应跳过哪些代码或您有什么。所以如果我有一个功能:func f(t *testing.T) {    defer func() {        if r := recover(); r != nil {            fmt.Println("Recovered in f", r)        }    }()    OtherFunctionThatPanics()    t.Errorf("The code did not panic")}我真的不知道是OtherFunctionThatPanics恐慌后我们恢复了,还是函数根本没有恐慌。如果没有恐慌,我如何指定跳过哪些代码,如果出现恐慌,我该如何指定执行哪些代码?我如何检查我们是否从中恢复了一些恐慌?
查看完整描述

3 回答

?
长风秋雁

TA贡献1757条经验 获得超7个赞

testing没有真正的“成功”的概念,只有失败。所以你上面的代码是正确的。您可能会发现这种风格更清晰一些,但它基本上是一样的。


func TestPanic(t *testing.T) {

    defer func() {

        if r := recover(); r == nil {

            t.Errorf("The code did not panic")

        }

    }()


    // The following is the code under test

    OtherFunctionThatPanics()

}

我通常发现testing相当弱。您可能对Ginkgo等更强大的测试引擎感兴趣。即使您不想要完整的 Ginkgo 系统,您也可以只使用它的匹配器库Gomega,它可以与testing. Gomega 包括匹配器,例如:


Expect(OtherFunctionThatPanics).To(Panic())

您还可以将恐慌检查包装成一个简单的函数:


func TestPanic(t *testing.T) {

    assertPanic(t, OtherFunctionThatPanics)

}


func assertPanic(t *testing.T, f func()) {

    defer func() {

        if r := recover(); r == nil {

            t.Errorf("The code did not panic")

        }

    }()

    f()

}


查看完整回答
反对 回复 2021-10-25
?
侃侃无极

TA贡献2051条经验 获得超10个赞

如果您使用testify/assert,那么它是单行的:


func TestOtherFunctionThatPanics(t *testing.T) {

  assert.Panics(t, OtherFunctionThatPanics, "The code did not panic")

}

或者,如果您OtherFunctionThatPanics的签名不是func():


func TestOtherFunctionThatPanics(t *testing.T) {

  assert.Panics(t, func() { OtherFunctionThatPanics(arg) }, "The code did not panic")

}

如果您还没有尝试过作证,那么也请查看testify/mock。超级简单的断言和模拟。


查看完整回答
反对 回复 2021-10-25
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

惯用标准库解决方案

对我来说,下面的解决方案很容易阅读,并向维护者展示了测试中的自然代码流。此外,它不需要第三方软件包。


func TestPanic(t *testing.T) {

    // No need to check whether `recover()` is nil. Just turn off the panic.

    defer func() { recover() }()


    OtherFunctionThatPanics()


    // Never reaches here if `OtherFunctionThatPanics` panics.

    t.Errorf("did not panic")

}

对于更通用的解决方案,您也可以这样做:


func TestPanic(t *testing.T) {

    shouldPanic(t, OtherFunctionThatPanics)

}


func shouldPanic(t *testing.T, f func()) {

    defer func() { recover() }()

    f()

    t.Errorf("should have panicked")

}


查看完整回答
反对 回复 2021-10-25
  • 3 回答
  • 0 关注
  • 209 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信