I would like to
testPanic1
simple
testPanic2
I prefer using this way because it is not enough to expect an error to occur. It should be precisely what the error is.
func testPanic1(testFunc func()) (isPanic bool) {
defer func() {
if err := recover(); err != nil {
isPanic = true
}
}()
testFunc()
return false
}
func TestPanic() {
fmt.Println(testPanic1(func() { panic("error...") })) // true
fmt.Println(testPanic1(func() { fmt.Println("") })) // false
}
func testPanic2(testFunc func()) (reason interface{}, isPanic bool) {
defer func() {
if err := recover(); err != nil {
reason = err
isPanic = true
}
}()
testFunc()
return nil, false
}
func TestPanic2() {
reason, isPanic := testPanic2(func() { panic("my error") })
fmt.Println(reason, isPanic) // "my error", true
reason, isPanic = testPanic2(func() { fmt.Println("") })
fmt.Println(reason, isPanic) // nil, false
}
More example
package _test
import (
"fmt"
"testing"
)
func testPanic(testFunc func()) (reason interface{}, isPanic bool) {
defer func() {
if err := recover(); err != nil {
reason = err
isPanic = true
}
}()
testFunc()
return nil, false
}
func TestPanicFunc(t *testing.T) {
if reason, isPanic := testPanic(func() {
panic("invalid memory address")
}); !isPanic || reason != "invalid memory address" {
t.Fatalf(`did not panic or panic msg != invalid memory address`)
}
if _, isPanic := testPanic(func() {
_ = fmt.Sprintln("hello world")
}); isPanic {
t.Fatalf("It shouldn't cause panic.")
}
var ps *string
if reason, isPanic := testPanic(func() {
fmt.Print(*ps)
}); !isPanic || reason.(error).Error() != "runtime error: invalid memory address or nil pointer dereference" {
t.Fatalf(`did not panic or panic msg != "runtime error: invalid memory address or nil pointer dereference"`)
}
}