Hello,
I’ve been writing some integration tests, and I’m using gorm as an ORM in my app. I’m trying to set up the tests such that all the database operations within the test is ran within a transaction and gets rolled-back every time, so that I can start with a clean slate everytime I run the test. Here is what I have for now:
// somewhere in helper package
func SetupTestDB() (*gorm.DB, func()) {
dbURI := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True", ....)
db, err := gorm.Open("mysql", dbURI)
if err != nil {
panic(err)
}
tx := db.Begin()
cleanup := func() {
tx.Rollback()
db.Close()
}
return tx, cleanup
}
// in the test itself
func TestDoSomething(t *testing.T) {
db, cleanup := tests.SetupTestDB()
defer cleanup()
user := factory.CreateUser(db)
service := someService.New(db)
// ....
service.DoSomethingElse(user, "param 1")
//
}
For the most part, it works.
But, every now and then, it seems to fail randomly, with errors indicating that the app couldn’t find the corresponding record from the DB even though it should’ve been created by the factory function calls in the test.
From the seemingly random nature of the error, I’d guess it has something to do with the way go run the tests in parallel? But I’m not sure where to begin investigating this because everything should be running in their own isolated transaction?