一、表格驱动测试
表格测试,把测试数据放在数据表格中进行多组数据测试
func Add(num1 int, num2 int) int {
return num1 + num2
}
func TestAdd(t *testing.T) {
type args struct {
num1 int
num2 int
}
testTable := []struct {
name string
args args
want int
}{
{
name: "Add",
args: args{1, 1},
want: 3,
},
{
name: "Add",
args: args{1, 0},
want: 1,
},
}
for _, tt := range testTable {
t.Run(tt.name, func(t *testing.T) {
if result := Add(tt.args.num1, tt.args.num2); result != tt.want {
t.Errorf(tt.name +" result is %v, want %v", result, tt.want)
}
})
}
}
二、mock函数测试
当要测试的函数依赖其他函数时,可以mock依赖函数进行测试
1、mock测试工具包
go get github.com/bouk/monkey
2、待测试函数Add()依赖函数calculate()
func Add(num1 int) int {
num2 := calculate()
return num1 + num2
}
func calculate() int {
//计算
return 1
}
3、测试示例
func TestAdd(t *testing.T) {
// 模拟calculate函数返回 1
guard := monkey.Patch(calculate, func() int {
return 1
})
guard.Unpatch()
type args struct {
num1 int
}
testTable := []struct {
name string
args args
want int
}{
{
name: "Add",
args: args{1},
want: 3,
},
{
name: "Add",
args: args{1},
want: 2,
},
}
for _, tt := range testTable {
t.Run(tt.name, func(t *testing.T) {
if result := Add(tt.args.num1); result != tt.want {
t.Errorf(tt.name+" result is %v, want %v", result, tt.want)
}
})
}
}
三、mock方法测试
1、待测试函数add(),依赖Adder的方法Calculate()
func Add(num1 int) int {
adder := &Adder{}
num2 := adder.Calculate()
return num1 + num2
}
type Adder struct {
}
func (adder *Adder) Calculate() int {
//计算
return 1
}
2、测试示例
func TestAdd(t *testing.T) {
adder := &Adder{}
// 模拟方法返回
guard := monkey.PatchInstanceMethod(reflect.TypeOf(adder), "Calculate", func(adder *Adder) int {
return 1
})
guard.Unpatch()
type args struct {
num1 int
}
testTable := []struct {
name string
args args
want int
}{
{
name: "Add",
args: args{1},
want: 2,
},
{
name: "Add",
args: args{0},
want: 1,
},
}
for _, tt := range testTable {
t.Run(tt.name, func(t *testing.T) {
if result := Add(tt.args.num1); result != tt.want {
t.Errorf(tt.name+" result is %v, want %v", result, tt.want)
}
})
}
}
四、mock数据库测试
github 官方示例
go get github.com/DATA-DOG/go-sqlmock
1、待测试内容
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func recordStats(db *sql.DB, userID, productID int64) (err error) {
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
switch err {
case nil:
err = tx.Commit()
default:
tx.Rollback()
}
}()
if _, err = tx.Exec("UPDATE products SET views = views + 1"); err != nil {
return
}
if _, err = tx.Exec("INSERT INTO product_viewers (user_id, product_id) VALUES (?, ?)", userID, productID); err != nil {
return
}
return
}
func main() {
// @NOTE: the real connection is not required for tests
db, err := sql.Open("mysql", "root@/blog")
if err != nil {
panic(err)
}
defer db.Close()
if err = recordStats(db, 1 /*some user id*/, 5 /*some product id*/); err != nil {
panic(err)
}
}
2、测试内容
package main
import (
"fmt"
"testing"
"github.com/DATA-DOG/go-sqlmock"
)
// a successful case
func TestShouldUpdateStats(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
mock.ExpectBegin()
mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()
// now we execute our method
if err = recordStats(db, 2, 3); err != nil {
t.Errorf("error was not expected while updating stats: %s", err)
}
// we make sure that all expectations were met
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}
// a failing test case
func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
mock.ExpectBegin()
mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec("INSERT INTO product_viewers").
WithArgs(2, 3).
WillReturnError(fmt.Errorf("some error"))
mock.ExpectRollback()
// now we execute our method
if err = recordStats(db, 2, 3); err == nil {
t.Errorf("was expecting an error, but there was none")
}
// we make sure that all expectations were met
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}