Go的五种mock技术

简介

良好的单元测试不仅可以在代码发布前验证代码是否可用,并且可以保护代码在以后的某一次修改中功能不被破坏。好的单元测试需要有自我隔离、可靠、无状态等特性。以下介绍五种 mock 技术。

1. Higher-Order Functions

当需要 mock 一个包级别函数的时候使用。

以下代码打开一个数据库连接:

func OpenDB(user, password, addr, db string) (*sql.DB, error) {
   
	conn := fmt.Sprintf("%s:%s@%s/%s", user, password, addr, db)
	return sql.Open("mysql", conn)
}

为了 mock 出 sql.Open,可以这样做:

type (
  // 将 sql 包的 sql.Open 函数保存在一个变量
	sqlOpener func(string, string) (*sql.DB, error)
)

// 现在调用 OpenDB 需要将 sql.Open 传入
func OpenDB(user, password, addr, db string, open sqlOpener) (*sql.DB, error) {
   
	conn := fmt.Sprintf("%s:%s@%s/%s", user, password, addr, db)
	return open("mysql", conn)
}

将直接在函数 OpenDB 调用 sql.Open 转化为:将 sqlOpener 函数作为入参。

在源码中只需将 sql.Open 函数显式传入,如下:

OpenDB(“myUser”, “myPass”, “localhost”, “foo”, sql.Open)

在测试时,可以这样 mock 出该 sql.Open 函数:

func TestOpenDB(t *testing.T) {
   
    mockError := errors.New("uh oh")
    subtests := []struct {
   
        name        string
        u, p, a, db string
        sqlOpener   func(string, string) (*sql.DB, error)
        expectedErr error
    }{
   
        {
   
            name: "happy path",
            u:    "u",
            p:    "p",
            a:    "a",
            db:   "db",
          // mock 出 sql.Open 函数,传入 OpenDB 方法。
            sqlOpener: func(s string, s2 string) (db *sql.DB, err error) {
   
                if s != "u:p@a/db" {
   
                    return nil, errors.New("wrong connection string")
                }
                return nil, nil
            },
        },
        {
   
            name: "error from sqlOpener",
            sqlOpener: func(s string, s2 string) (db *sql.DB, err error
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值