为所有测试文件初始化一次某个东西,并在它们的init()函数中使用它。

huangapple go评论85阅读模式
英文:

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
}

https://play.golang.org/p/j1LFy0n1AsG

huangapple
  • 本文由 发表于 2021年7月28日 18:43:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/68558920.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定