I'm currently pondering how to write tests that check if a given piece of code panicked? I know that Go uses recover
to catch panics, but unlike say, Java code, you can't really specify what code should be skipped in case of a panic or what have you. So if I have a function:
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") }
I can't really tell whether OtherFunctionThatPanics
panicked and we recovered, or if the function did not panic at all. How do I specify which code to skip over if there is no panic and which code to execute if there is a panic? How can I check whether there was some panic we recovered from?
testing
doesn't really have the concept of "success," only failure. So your code above is about right. You might find this style slightly more clear, but it's basically the same thing.
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() }
I generally find testing
to be fairly weak. You may be interested in more powerful testing engines like Ginkgo. Even if you don't want the full Ginkgo system, you can use just its matcher library, Gomega, which can be used along with testing
. Gomega includes matchers like:
Expect(OtherFunctionThatPanics).To(Panic())
You can also wrap up panic-checking into a simple function:
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() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With