如何测试恐慌?

新手上路,请多包涵

我目前正在考虑如何编写测试来检查给定的代码段是否出现恐慌?我知道 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 恐慌并且我们恢复了,或者该功能是否根本没有恐慌。如何指定在没有恐慌时跳过哪些代码以及在出现恐慌时执行哪些代码?我如何检查我们是否从恐慌中恢复过来了?

原文由 ThePiachu 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 602
2 个回答

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()
}

原文由 Rob Napier 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果您使用 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,那么也可以查看 testify/mock 。超级简单的断言和模拟。

原文由 Jacob Marble 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题