DATA-DOG / go-txdb

Immutable transaction isolated sql driver for golang
Other
667 stars 48 forks source link

Can´t get it to work with Gorm V2. #36

Closed brpaz closed 4 years ago

brpaz commented 4 years ago

Hello.

I am trying to use txdb in my database integration tests together with Gorm V2, but it´s not going well.

Here is my test code:

func TestPgRepository_CreateTodo(t *testing.T) {
    db := testutil.GetTestDBConnection()

    defer testutil.CloseDb(db)

    repo := todo.NewPgRepository(db)

    td, err := repo.CreateTodo(todo.Todo{
        Description: "some-todo",
        CreatedAt: time.Now(),
    })

    assert.Nil(t, err)
    assert.NotNil(t, td.ID)
}

func TestPgRepository_FindAll(t *testing.T) {
    db := testutil.GetTestDBConnection()

    defer testutil.CloseDb(db)

    repo := todo.NewPgRepository(db)

    // Create test data
    r := db.Create(&todo.GormTodo{
        Description: "TODO 1",
        CreatedAt: time.Now(),
    })

    fmt.Println(r.Error)
    result, err := repo.FindAll()

    assert.NotNil(t, err)
    assert.Len(t, result, 1)
}

When testing the FindAll method it returns 2 records, so the transaction is not being rollback.

And here is the code of my GetTestDBConnection

func GetTestDBConnection() *gorm.DB {

    dbHost := os.Getenv("DB_HOST")
    dbPort := os.Getenv("DB_PORT")
    dbUser := os.Getenv("DB_USER")
    dbPassword := os.Getenv("DB_PASSWORD")
    dbName := GetTestDBName()

    dsn := fmt.Sprintf("host=%v user=%v password=%v dbname=%v port=%v sslmode=disable",
        dbHost,
        dbUser,
        dbPassword,
        dbName,
        dbPort,
    )

    once.Do(func() {
        txdb.Register("tx_test", "postgres", dsn)
    })

    db, err := gorm.Open(gormPG.Open(dsn), &gorm.Config{})

    if err != nil {
        panic(err)
    }

    return db
}

Gorm changed the Open method signature, so now has to receive a Dialect struct instead the driver name. The only link between txdb and GORM in this example is the dsn. not sure if it´s enough.

I tried to use a persistent connection instead of creating a new one for each est but then I can´t close the connection and thus the transaction are not rollback, otherwise the subsequence tests will complain the connection is closed

I also tried to register a txdb for each test with a random name to avoid conflicts but it also doesnt seem to work. It should IMO, since each test is opening and closing a connection, so I guess it´s really GORM not using txdb correctly.

Any ideas?

Thank you

brpaz commented 4 years ago

Well, I think I managed to do it natively with Gorm without needing txdb, by just creating a transaction and pass it to the repository instead of the db instance:

func TestPgRepository_CreateTodo(t *testing.T) {
    db := testutil.GetTestDBConnection()

    tx := db.Begin()
    defer tx.Rollback()

    repo := todo.NewPgRepository(tx)

    td, err := repo.CreateTodo(todo.Todo{
        Description: "some-todo",
        CreatedAt: time.Now(),
    })

    assert.Nil(t, err)
    assert.NotNil(t, td.ID)
}

Feel free to close this issue, but still I would like to know if it would be possible to get it work with txdb

l3pp4rd commented 4 years ago

Hi, I do not use GORM, but you need to use tx_test dsn if you register txdb under that one

nickdelja commented 3 years ago

I was able to get it working with the following:

txdb.Register("txdb", "postgres", os.Getenv("DB_CONNECTION_TEST"))
db, err = gorm.Open(
    postgres.New(postgres.Config{
        DriverName: "txdb",
    }),
    &gorm.Config{},
)
if err != nil {
    return nil, err
}
theN0b0dy commented 3 years ago

thanks @nickdelja , you saved my ass somehow