子嘉的博客 子嘉的博客
首页
bic-bic
技术
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

高子嘉

没有比脚更长的路,没有比人更高的山
首页
bic-bic
技术
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • 博客搭建

  • 服务端

  • distributed

  • golang

    • gomod
    • compile
    • code_snippet

    • protobuf
    • 单元测试
      • 单元编写
        • 简单示例
        • mock 使用
        • mysql mock
        • Redis mock
        • Casbin mock
        • Func mock
        • Goroutine mock
        • 基准测试
        • 测试报告
    • script

  • db

  • docker

  • linux

  • 技术
  • golang
子嘉
2023-03-21
目录

单元测试

# golang 单元测试

本单元测试基于 golang gin 项目,使用 mysql、redis 数据库,权限控制使用 casbin

# 单元编写

# 简单示例

func genVersionNumber(version string) int {
   var vn = 1
   if strings.HasPrefix(version, "v") {
      vs := strings.Split(version[1:], "-")
      for _, v := range vs {
         vn *= 1000
         if n, err := strconv.Atoi(v); err != nil {
            return 0
         } else {
            vn = vn + n
         }
      }
   }
   return vn
}

func Test_genVersionNumber(t *testing.T) {
   type args struct {
      version string
   }
   tests := []struct {
      name string
      args args
      want int
   }{
      {"测试1", args{version: "v1-2-3"}, 1001002003},
      {"测试2", args{version: "v1-12-3"}, 1001012003},
      {"测试3", args{version: "v1-2-30"}, 1001002030},
      {"测试4", args{version: "v1-21-3"}, 1001021003},
      {"测试5", args{version: "v12-2-3"}, 1012002003},
   }
   for _, tt := range tests {
      t.Run(tt.name, func(t *testing.T) {
         assert.Equalf(t, tt.want, genVersionNumber(tt.args.version), "genVersionNumber(%v)", tt.args.version)
      })
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# mock 使用

# mysql mock

Gorm 库:gorm.io/gorm v1.23.8 Gorm mock 库:github.com/DATA-DOG/go-sqlmock v1.5.0

  1. 启动 sql mock
func SetupMock() {
  // mock sql.DB
  sqlDB, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherRegexp))
  if err != nil {
     panic(err)
  }
  // open gorm db
  gdb, err := gorm.Open(mysql.New(mysql.Config{Conn: sqlDB, SkipInitializeWithVersion: true}), &gorm.Config{
     Logger: glog.ExportGormLogger(500 * time.Millisecond).LogMode(logger.Silent),
  })
  if err != nil {
     panic(err)
  }
  mysqlDatabase = gdb
  mysqlMock = mock
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. Query mock
db.SqlDBMock().ExpectQuery("^SELECT (.+) FROM `accounts` (.*)$").
    WithArgs(1, 2, 12).
    WillReturnRows(
       sqlmock.NewRows([]string{"ID", "CreateAt", "studio_id"}).
       AddRow(1, time.Now(), 1).
       AddRow(2, time.Now(), 1),
    )
1
2
3
4
5
6
7
  1. Transaction mock
db.SqlDBMock().ExpectBegin()
db.SqlDBMock().ExpectExec("^UPDATE `accounts` (.*)$").
    WillReturnResult(sqlmock.NewResult(1, 1))
db.SqlDBMock().ExpectCommit()
1
2
3
4

# Redis mock

使用 redis 库 github.com/redis/go-redis/v9 使用 redis mock 库 github.com/go-redis/redismock/v9

rdb, mock = redismock.NewClientMock()
1
func TestCheckRedisBiDate(t *testing.T) {
   ctx := context.Background()
   mm := db.SetupMockRedis()
   date := "2023-03-01"

   redisKey := fmt.Sprintf(RedisBIDate, date)
   mm.ExpectGet(redisKey).SetErr(errors.New("mock error"))
   ok := CheckRedisBiDate(ctx, date)
   assert.False(t, false, ok)

   mm.ExpectGet(redisKey).SetVal("0")
   ok = CheckRedisBiDate(ctx, date)
   assert.False(t, false, ok)

   mm.ExpectGet(redisKey).SetVal("1")
   ok = CheckRedisBiDate(ctx, date)
   assert.False(t, false, ok)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Casbin mock

使用 casbin 库:github.com/casbin/casbin/v2 v2.60.0 使用 casbin sql adapter:github.com/casbin/gorm-adapter/v3 v3.7.4 使用 casbin mock adapter:github.com/ShuaiGao/string-adapter v0.1.1

  1. 启动 casbin mock
func SetupMock() {
   // casbin mock,只需要定制一个 adapter
   a := sa.NewAdapter(&policy)
   setup("", a)
}
1
2
3
4
5
  1. 添加权限
var userSub = permission.GetUserSub("zijia")
var resourceGroupSub = permission.GetGroupResourceSub("zijia")

_, _ = permission.Enforcer().AddRoleForUser(userSub, resourceGroupSub)
_, _ = permission.Enforcer().AddPolicy(resourceGroupSub, string(permission.CasbinStudio), "12")
1
2
3
4
5

# Func mock

Gomonkey 库:github.com/agiledragon/gomonkey/v2 v2.9.0

patch := gomonkey.ApplyFunc(Add, func(a, b int) {
    return a+b
})
defer patch.Reset()
1
2
3
4

# Goroutine mock

Gomonkey 库:github.com/agiledragon/gomonkey/v2 v2.9.0 方法替换的实现原理:替换对应方法的指针

ctx := &gin.Context{Request: &http.Request{}}
ctx.Set(utils.USER_SUB, userSub)
timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx.Request.WithContext(timeoutCtx)
goMonkeyCounter := 0
blockChannel := make(chan bool)
patches := gomonkey.ApplyFunc(UpdateReportPlatform, func(_ context.Context, _ ...*model.Account) {
   goMonkeyCounter++
   blockChannel <- true
})
defer func() {
   select {
   case <-timeoutCtx.Done():
      break
   case <-blockChannel:
      break
   }
   patches.Reset()
   assert.Equal(t, 1, goMonkeyCounter)
}()
_, code = PostAdvertisersBatch(ctx, in)
assert.Equal(t, 0, code)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 基准测试

参考其博客链接 https://blog.csdn.net/qq_39787367/article/details/113989485

# 测试报告

# 查看覆盖率
$ go test -cover
# 加入-coverprofile 参数,将覆盖率输出到文件
$ go test -cover -coverprofile=c.out ./...
# 查看输出文件
$ go tool cover -html=c.out
1
2
3
4
5
6
编辑 (opens new window)
#golang#单元测试
上次更新: 2023/03/21, 12:47:55
protobuf
auto_build

← protobuf auto_build→

最近更新
01
mongodb restore
03-06
02
pytesseract
02-28
03
consul
02-24
更多文章>
Theme by Vdoing | Copyright © 2022-2025 子嘉 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式