まとめ
Go
でSQL
のテストを書くときはgo-sqlmockを使うとデータベースのモックがかんたんに作れる.
環境
- macOS Big Sur 11.2.3
- go version go1.15.5 darwin/amd64
- go-sqlmock v1.5.0
やりかた
こんな感じでDB(MySQL
)のテーブル操作(CRUD)を行う関数について, ユニットテストを書きたくなった.
テスト用のDBを立てて実際に操作しても良いんだけど,
CIするときに面倒だったりするのでできればGo
だけでDBをモックして完結したテストを書きたい.
こんなときにはgo-sqlmockが使える.
公式README1を参考にしながら関数Create()
についてテストを書いてみるとこんな感じ.
Arrange
でDBのモックを作成し, 想定される引数に対する挙動を設定している.
エラーの有無や返す値の内容などもmock.Expect~().With~().With~()
2で細かく設定できる.
同様にRead()
, Update()
, Delete()
についても書いていく.
最終的なテストコードはこんな感じ.
最後にテストを実行してみる.
$ tree .
.
├── go.mod
├── go.sum
├── main.go
└── main_test.go
# テスト実行
$ go test -v ./...
=== RUN TestCreate
=== RUN TestCreate/Createが成功するケース
=== RUN TestCreate/Createが失敗するケース
--- PASS: TestCreate (0.00s)
--- PASS: TestCreate/Createが成功するケース (0.00s)
--- PASS: TestCreate/Createが失敗するケース (0.00s)
=== RUN TestRead
=== RUN TestRead/Readが成功するケース
=== RUN TestRead/Readが失敗するケース(QueryRowでエラー)
=== RUN TestRead/Readが失敗するケース(Scanでエラー)
--- PASS: TestRead (0.00s)
--- PASS: TestRead/Readが成功するケース (0.00s)
--- PASS: TestRead/Readが失敗するケース(QueryRowでエラー) (0.00s)
--- PASS: TestRead/Readが失敗するケース(Scanでエラー) (0.00s)
=== RUN TestUpdate
=== RUN TestUpdate/Updateが成功するケース
=== RUN TestUpdate/Updateが失敗するケース
--- PASS: TestUpdate (0.00s)
--- PASS: TestUpdate/Updateが成功するケース (0.00s)
--- PASS: TestUpdate/Updateが失敗するケース (0.00s)
=== RUN TestDelete
=== RUN TestDelete/Deleteが成功するケース
=== RUN TestDelete/Deleteが失敗するケース
--- PASS: TestDelete (0.00s)
--- PASS: TestDelete/Deleteが成功するケース (0.00s)
--- PASS: TestDelete/Deleteが失敗するケース (0.00s)
PASS
ok github.com/uzimihsr/golang-db-test 0.170s
できた.
おわり
go-sqlmock
を使うことで, テスト用のDBを立ち上げることなくGo
でSQL
のテストができた. べんり.