🎉
【Go】gorm❌sql-mockの使い方
背景
バイトでmockのテストを書くときに使うことになったので、基本的なことを抑えるために記事にしました。
sql-mockとは
sql-mockとはデータベースを使うテストを実行するときに用いるものです。テストをする時に元々用意してあるデータベースを使ってテストをすることはない。そこで、テスト用のデータ(mock)を別に用意をして、データベースを扱うテストを行う。goであればsql-mockを用いることが多い。
テスト例
こちらのuserを作成するメソッドをテストしていきます。
controller.go
func Post(db *gorm.DB, name string, password string) *models.User {
user := models.User{}
var err error
user.Name = name
user.Password, err = handler.PasswordEncrypt(password)
user.UUID = uuid.New().String()
user.Created_at = time.Now()
if err != nil {
fmt.Println("パスワード暗号化中にエラーが発生しました。:", err)
}
db.Create(&user)
return &user
}
次にテストで使うデータベースを作成します。
mock/db.go
package mock
import (
"github.com/DATA-DOG/go-sqlmock"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func GetNewDbMock() (*gorm.DB, sqlmock.Sqlmock, error) {
db, mock, err := sqlmock.New()
if err != nil {
return nil, mock, err
}
gormDB, err := gorm.Open("mysql", db) //通常ならここにdbのurlが入るが、テストの場合はmockで作ったdbを入れる。
if err != nil {
return gormDB, mock, err
}
return gormDB, mock, err
}
次にテストを作成します。
controller_test.gpo
func TestPost(t *testing.T) {
db, mock, err := mock.GetNewDbMock()
if err != nil {
t.Errorf("Failed to initialize mock DB: %v", err)
return
}
var id int = 1
var name string = "user1"
// Mock設定発酵されたクエリが正しいかどうかを確認す
mock.ExpectBegin()
mock.ExpectQuery(`INSERT INTO "users" (.+) RETURNING`).
WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(id, name))
mock.ExpectCommit()
res, err := CreateTag(db, "user1")
assert.Equal(t, *res.ID, id)
assert.Equal(t, res.Name, name)
}
ExpectBegin()
:処理を開始する関数
ExpectQuery
:期待するSELECT文と取得結果の組み合わせをモック化します。
WillReturnRows
:期待する取得結果に必要なカラムを指定します。
NewRows
:返り値としてNewRows関数を指定します。
ExpectCommit
:コミットを期待する関数
最後に
sql-mockを使ったのでまとめてみました。まだ、他にも使い方があるので、もう少し勉強します!
Discussion