Running DB operations in transaction for test

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?

Nevermind, figured out the issue. Silly thing, nothing to do with the transaction or race condition, it turns out.

One of the factory method uses a faker library to generate slugs, and every now and then, it generates a slug that is longer than the field on the database, which gets automatically trimmed out.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.