GORM (https://github.com/jinzhu/gorm)
を使っているプロジェクトのDB接続をstubするために色々調べた時のメモ。
最初、go-sqlmock (https://github.com/DATA-DOG/go-sqlmock)
を見つけて、これ使えば簡単にいけそうだなーと思って調べてみたらGORM側のsql.DBを保持しているフィールドが隠蔽されていてどうしたものかと悩んだ。
しばらくソースを読んでいると、Open()を呼ぶ際に引数として渡すドライバ名とデータソース名でsql.Open()を呼んでいて、その結果をそのままDB structのフィールドに保持しているということが分かった。
https://github.com/jinzhu/gorm/blob/8b058a707f156b411e280bc55c5aa20544e64873/main.go#L61
sql-mockのソースコードも読んでみると、sqlmockという名前でドライバが登録されており、NewWithDSNという関数を使えばデータソース名を引数にDB接続を取得できることが分かった。
https://github.com/DATA-DOG/go-sqlmock/blob/master/driver.go#L16
https://github.com/DATA-DOG/go-sqlmock/blob/master/driver.go#L67
参考:database/sqlインターフェース https://astaxie.gitbooks.io/build-web-application-with-golang/ja/05.1.html
というわけで
var db *gorm.DB
_, mock, err := sqlmock.NewWithDSN("sqlmock_db_0")
if err != nil {
panic("Got an unexpected error.")
}
db, err = gorm.Open("sqlmock", "sqlmock_db_0")
if err != nil {
panic("Got an unexpected error.")
}
defer db.Close()
rs := sqlmock.NewRows([]string{"count"}).FromCSVString("1")
mock.ExpectQuery(`SELECT count.* FROM "whitelist" WHERE.*$`).
WithArgs(12345).
WillReturnRows(rs)
....
....
こんな感じでDB接続をstubできるようになりました。