英文:
Initialise something once for all test files, and use it in their init()
问题
我想要初始化一个数据库连接,该连接将在多个测试文件的init()函数中使用。
我希望只初始化一次数据库连接,并重复使用该连接,而不是在每个测试文件的init()函数中初始化连接。
这似乎是TestMain的一个使用案例,然而TestMain似乎在文件的init()函数之后运行(这让我感到有点奇怪,因为TestMain似乎用于对测试进行一次性全局初始化):
type DB struct {
	session string
}
var db = DB{session: "disconnected"}
func TestMain(m *testing.M) {
	// 我们希望在这里初始化一次DB连接,供所有测试文件使用
	db = DB{session: "connected"}
	exitVal := m.Run()
	os.Exit(exitVal)
}
func init() {
	// 我们想要在这里使用DB连接进行一些初始化
	// 我们有多个测试文件,每个文件都有一个init()函数,但它们都应该使用同一个db连接
	// 不幸的是,测试文件的init()函数似乎在全局调用TestMain之后被调用
	fmt.Println(db.session)
}
func TestThatNeedsDBInitializedByInitFunction(t *testing.T) {
	// 需要在测试文件的init()函数中初始化DB的一些测试
}
输出(注意DB连接未初始化):
disconnected
=== RUN   TestThatNeedsDBInitializedByInitFunction
--- PASS: TestThatNeedsDBInitializedByInitFunction (0.00s)
PASS
ok  	github.com/fakenews/x	0.002s
鉴于我们不能使用TestMain来实现这一点,我们如何在全局范围内为所有测试文件初始化一次,并在测试文件的init()函数中使用它呢?
英文:
I want to initialize a DB connection that will be used by multiple test files in their init().
I would like to only initialize the DB connection once, and reuse the connection, instead of initializing the connection in init() in every test file.
This seemed like a use case for TestMain, however TestMain appears to run after a file's init() (which I find a bit weird given that TestMain appears to be used to do some one-off global initialization for tests):
type DB struct {
	session string
}
var db = DB{session: "disconnected"}
func TestMain(m *testing.M) {
	// We would like to init the DB connection once here, for all of our test files
	db = DB{session: "connected"}
	exitVal := m.Run()
	os.Exit(exitVal)
}
func init() {
	// We want to do some initialization with a DB connection here
	// We have multiple test files, each with an init, but they should all use the same db
	// connection
	// Unfortunately, a test file's init() seems to be called _after_ TestMain is called once
	// globally
	fmt.Println(db.session)
}
func TestThatNeedsDBInitializedByInitFunction(t *testing.T) {
	// some test that requires DB initalization in the test file's init()
}
Output (note the DB connection is not initialized):
disconnected
=== RUN   TestThatNeedsDBInitializedByInitFunction
--- PASS: TestThatNeedsDBInitializedByInitFunction (0.00s)
PASS
ok  	github.com/fakenews/x	0.002s
Given that we can't use TestMain for this, how do we initialize something once globally for all test files in a way that we can use it in a test file's init()?
答案1
得分: 4
你可以使用立即调用的函数字面量来初始化顶层的db变量。
var db = func() DB {
    // 在init()之前执行的一些连接逻辑
    return DB{session: "connected"}
}()
func init() {
    fmt.Println(db.session) // connected
}
链接:https://play.golang.org/p/j1LFy0n1AsG
英文:
You can initialize the top-level db variable using a function literal that you call immediately.
var db = func() DB {
    // some connection logic that should be executed before init()
    return DB{session: "connected"}
}()
func init() {
    fmt.Println(db.session) // connected
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论