1

I'm using mysql transaction in my project, I want to know how to write unit test when using db transaction? for example:

func SomeFunc() error {
  return db.Transaction(func(tx *gorm.DB) {
    // my business logic goes below
    tx.Select(xxx)
    tx.Create(xxx)
    tx.Delete(xxx)
  }) 
}

What's I think is that I rely on gorm strongly, that's may be bad. Do I need to define a trancation interface for only unit test?

user229044
  • 232,980
  • 40
  • 330
  • 338
lee3164
  • 21
  • 2
  • 1
    have a look at github.com/DATA-DOG/go-sqlmock if you really want to do this, BUT this is arguably something that may provide more insights if you run integration tests against a dummy database spawned in docker or other light runtime that's convenient for your needs(sometimes it is easier to spot unexpected concurrency issues, max_connections issues, db dead locks, read phenomena against a real database that you're planning to use) – Neo Anderson Apr 14 '23 at 21:48

1 Answers1

2

one way to write a test when you have to test a database is always to bring up an in-memory database to test it or a real database with fake data I encourage you to write tests in this way not unit tests because in unit tests all your testing is the fake or dummy that you write here is an example of what I mean:

import (
    "testing"
    "database/sql"
    _ "github.com/mattn/go-sqlite3" // import the sqlite driver
)

func TestMyFunction(t *testing.T) {
    db, err := sql.Open("sqlite3", ":memory:") // use an in-memory sqlite database for testing
    if err != nil {
        t.Fatal(err)
    }
    defer db.Close()

tx, err := db.Begin()
if err != nil {
    t.Fatal(err)
}
defer tx.Rollback() // rollback the transaction at the end of the test

// Execute your code under test within the transaction
// ...

err = tx.Commit() // commit the transaction if there were no errors
if err != nil {
    t.Fatal(err)
}

// Check the results of your code under test
// ...

}