dbzuk
dbzuk

Reputation: 255

Initialise something once for all test files, and use it in their 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()?

Upvotes: 1

Views: 535

Answers (1)

mkopriva
mkopriva

Reputation: 38333

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

Upvotes: 4

Related Questions