Golang Test SQL CRUD
use golang with sqlc to test CRUD
install library
go get github.com/lib/pq
go get github.com/stretchr/testify/require
編寫測試單元
//main_test.go
package db
import (
"database/sql"
"log"
"os"
"testing"
_ "github.com/lib/pq"
)
var testQueries *Queries
const(
dbDriver = "postgres"
dbHost = "postgresql://root:password@localhost:5432/simple_bank?sslmode=disable"
)
func TestMain(m *testing.M){
conn,err := sql.Open(dbDriver,dbHost)
if err != nil {
log.Println("connnect error")
}
testQueries = New(conn)
os.Exit(m.Run())
}
測試是否能插入數據
//account_test.go
package db
import (
"context"
"testing"
"github.com/stretchr/testify/require"
)
func TestAccount(t *testing.T){
args := CreateAccountParams{
Owner: "peter",
Balance: 10000,
Currency: "NT",
}
account,err := testQueries.CreateAccount(context.Background(),args)
require.NoError(t,err)
require.NotEmpty(t,account)
require.Equal(t,args.Owner,account.Owner)//檢查args的和輸入的參數比對
require.Equal(t,args.Balance,account.Balance)
require.Equal(t,args.Currency,account.Currency)
require.NotZero(t,account.ID)//檢查id自動輸入
require.NotZero(t,account.CreateAt)//檢查時間自是否自動輸入
}
使用隨機數值來增加新能
- 新增util/random
package util
import (
"math/rand"
"strings"
"time"
)
var alphet = "abcdefghijklmnopqrstuvwxyz"
func init(){//init函數將在第一次使用包時自動調用
rand.Seed(time.Now().UnixNano()) //使用time.Now.UnixNano確保每次值都不一樣
}
func RandimInt(min,max int64)int64{
return min+rand.Int63n(max-min + 1)
//rand.Int63n(n)會返回0和n-1之間的數
}
func RandString(n int)string{
var sb strings.Builder
k := len(alphet)
for i:=0;i<n;i++{
c := alphet[rand.Intn(k)] //rand.Intn(k)返回0~k-1的隨機位置,並取得那位置的字符
sb.WriteByte(c) //調用sb.WriteByte將字符c寫入生成器
}
return sb.String()
}
func RandomOwner()string{
return RandString(6)
}
func RandomMonney()int64{
return RandimInt(0,1000)
}
func RandomCurrency()string{
currencies := []string{"NT","US","JP"}
c := len(currencies)
return currencies[rand.Intn(c)] //返回字符串隨機索引
}
修改測試插入數據
args := CreateAccountParams{
Owner:util.RandomOwner(),
Balance: util.RandomMonney(),
Currency: util.RandomCurrency(),
}
account,err := testQueries.CreateAccount(context.Background(),args)
require.NoError(t,err)
require.NotEmpty(t,account)
require.Equal(t,args.Owner,account.Owner)//檢查args的和輸入的參數比對
require.Equal(t,args.Balance,account.Balance)
require.Equal(t,args.Currency,account.Currency)
require.NotZero(t,account.ID)//檢查id自動輸入
require.NotZero(t,account.CreateAt)//檢查時間自是否自動輸入
return account
測試查詢單一數據
func TestGetAccount(t *testing.T){
account1 := createRandomAccount(t)
account2,err :=testQueries.GetAccount(context.Background(),account1.ID)
require.NoError(t,err)
require.NotEmpty(t,account2)
require.Equal(t,account1.ID,account2.ID)
require.Equal(t,account1.Owner,account2.Owner)
require.Equal(t,account1.Balance,account2.Balance)
require.Equal(t,account1.Currency,account2.Currency)
require.WithinDuration(t,account1.CreateAt.Time,account2.CreateAt.Time, time.Second)
//檢查時間軸是否一樣
}
測試查詢多重數據
func TestListGetAccount(t *testing.T){
for i := 0; i < 10; i++ {
createRandomAccount(t)
}
args := ListAccountsParams{
Limit: 5,
Offset: 5,
}//代表跳過前5項,並返回接下來的5項 =>查詢5項
account1,err := testQueries.ListAccounts(context.Background(),args)
require.NoError(t,err)
require.Len(t,account1,5)//要求返回切片長度為5
for _,v := range account1{
require.NotEmpty(t,v)
}
}
測試修改數據
func TestUpdateAccount(t *testing.T){
account1 := createRandomAccount(t)
args := UpdateAuthorBiosParams{
ID: account1.ID,
Balance: util.RandomMonney(),
}
account2,err := testQueries.UpdateAuthorBios(context.Background(),args)
require.NoError(t,err)
require.NotEmpty(t,account2)
require.Equal(t,account1.ID,account2.ID)
require.Equal(t,account1.Owner,account2.Owner)
require.Equal(t,args.Balance,account2.Balance)
require.Equal(t,account1.Currency,account2.Currency)
require.WithinDuration(t,account1.CreateAt.Time,account2.CreateAt.Time, time.Second)//檢查時間軸是否一樣
}
測試刪除數據
func TestDeleteAccount(t *testing.T){
account1 := createRandomAccount(t)
err := testQueries.DeleteAccount(context.Background(),account1.ID)
require.NoError(t,err)
account2,err := testQueries.GetAccount(context.Background(),account1.ID)
require.NoError(t,err)
require.EqualError(t,err,sql.ErrNoRows.Error())
require.NotEmpty(t,account2)
}