英文:
testing.M recover in golang
问题
这是一个恢复(recover)工作的例子:
func TestSomeTest(t *testing.T) {
    defer func() {
        r := recover()
        fmt.Println("recovery")
        fmt.Println(r)
    }()
    panic("panic here")
}
但是这个例子不起作用:
func TestSomeTest(t *testing.T) {
    panic("panic here")
}
func TestMain(m *testing.M) {
    defer func() {
        r := recover()
        fmt.Println("recovery")
        fmt.Println(r)
    }()
    ret := m.Run()
    os.Exit(ret)
}
为什么呢?我期望panic here会被func TestMain(m *testing.M)中的代码恢复(recover)。为什么没有呢?在这种情况下,我只有panic而没有任何recovery。
完整代码:
package main
import (
    "fmt"
    "os"
    "testing"
)
func TestSomeTest(t *testing.T) {
    // defer func() {
    //     r := recover()
    //     fmt.Println("recovery")
    //     fmt.Println(r)
    // }()
    panic("panic here")
}
func TestMain(m *testing.M) {
    defer func() {
        r := recover()
        fmt.Println("recovery")
        fmt.Println(r)
    }()
    ret := m.Run()
    os.Exit(ret)
}
我使用go test命令来运行这段代码。
英文:
This recovery works:
func TestSomeTest(t *testing.T) {
	defer func() {
		r := recover()
		fmt.Println("recovery")
		fmt.Println(r)
	}()
	panic("panic here")
}
But this does not:
func TestSomeTest(t *testing.T) {
	panic("panic here")
}
func TestMain(m *testing.M) {
	defer func() {
		r := recover()
		fmt.Println("recovery")
		fmt.Println(r)
	}()
	ret := m.Run()
	os.Exit(ret)
}
Why?
I expect that panic here will be recovered by code in func TestMain(m *testing.M). Why not? I just have panic without any recovery in this case.
Full code:
package main
import (
	"fmt"
	"os"
	"testing"
)
func TestSomeTest(t *testing.T) {
	// defer func() {
	// 	r := recover()
	// 	fmt.Println("recovery")
	// 	fmt.Println(r)
	// }()
	panic("panic here")
}
func TestMain(m *testing.M) {
	defer func() {
		r := recover()
		fmt.Println("recovery")
		fmt.Println(r)
	}()
	ret := m.Run()
	os.Exit(ret)
}
To run this code I used go test command.
答案1
得分: 8
这是因为测试是在单独的goroutine中运行。
就好像你的第一个示例发送了一个无法恢复的goroutine。
func TestSomeTest(t *testing.T) {
    defer func() {
        r := recover()
        fmt.Println("recovery")
        fmt.Println(r)
    }()
    go func() {
        // 不会恢复
        panic("panic here")
    }()
    time.Sleep(time.Second)
}
英文:
It's because the tests are run in separate goroutines.
It's like if your fist example sent off a goroutine, which can't be recovered.
func TestSomeTest(t *testing.T) {
    defer func() {
        r := recover()
        fmt.Println("recovery")
        fmt.Println(r)
    }()
    go func() {
        // won't recover
        panic("panic here")
    }()
    time.Sleep(time.Second)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论