千家信息网

编写可测试的better go代码示例分析

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,今天给大家介绍一下编写可测试的better go代码示例分析。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。在开发一个接
千家信息网最后更新 2026年11月01日编写可测试的better go代码示例分析

今天给大家介绍一下编写可测试的better go代码示例分析。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。

在开发一个接口的时候,通常要引入数据库、redis、或者内部调用其他服务,单元测试需要先将对应的数据库、redis、第三方服务都启动,不然,没法做单元测试。 下面就是解决这种情况,原则上认为底层相关服务都已经经过了严格的单元测试,所以将相关的方法提取出来,在单元测试的时候,模拟替换实际的数据库、redis、或其他内部的服务。

一个普通的例子

下面启动了一个http服务,对外提供一个/bad接口,这个接口的功能就是接收一个string类型的参数 args,并通过db查询出apps

//better/main.gopackage mainimport (    "errors"    "net/http"    "better/service"    "github.com/jinzhu/gorm")func main() {    http.HandleFunc("/bad", func(w http.ResponseWriter, r *http.Request) {        args := r.URL.Query().Get("args")        //init db        db, err := dao.NewStorage()        if err != nil {            w.Write([]byte(err.Error()))            w.WriteHeader(http.StatusBadRequest)            return        }        apps, err := service.NewHandle().GetApps(args, db.DB)        if err != nil {            w.Write([]byte(err.Error()))            w.WriteHeader(http.StatusBadRequest)            return        }        w.Write([]byte(apps))        w.WriteHeader(http.StatusOK)        return    })    err := http.ListenAndServe(":8080", nil)    if err != nil {        panic(err)    }}

service层

//better/service/bad.gopackage serviceimport (    "errors"    "github.com/jinzhu/gorm")type handle struct {}func NewHandle() *handle {    return &handle{}}func (h handle) GetApps(args string, db *gorm.DB) (apps string, err error) {    if args == "" {        return "", errors.New("args is nil")    }    //引入 db    err = db.Find(&apps).Error    if err != nil {        return "", err    }    return apps, nil}

数据库层

//better/dao/apps.gopackage daoimport "github.com/jinzhu/gorm"type Storage struct {    DB *gorm.DB}func NewStorage() (*Storage, error) {    db, err := gorm.Open("user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local")    if err != nil {        return nil, err    }    return &Storage{DB: db}, nil}func (s *Storage) GetApps() (string, error) {    return "dao apps", nil}

单元测试代码

//better/service/bad_test.gopackage serviceimport (    "testing"    "github.com/jinzhu/gorm")func Test_GetApps(t *testing.T) {    db, err := gorm.Open("user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local")    if err != nil {        t.Fatal("gorm open err", err.Error())    }    _, err = NewHandle().GetApps("test", db)    if err != nil {        t.Fatal("getApps err", err.Error())    }    t.Log("success")}

如果要针对func (h handle) getApps(args string, db *gorm.DB) (apps string, err error) 这个方法进行单元测试,我们就不得不启动一个mysql,这样单元测试代码就db严重耦合了。如果方法内部还涉及了调用其他服务,我们还得启动其他服务,这样单元测试写起来就非常不方便。

一种更好的实现方式

新增一个better接口

//better/main.gopackage mainimport (    "net/http"    "better/dao"    "better/service"    "github.com/jinzhu/gorm")func main() {    http.HandleFunc("/better", func(w http.ResponseWriter, r *http.Request) {        args := r.URL.Query().Get("args")        //init db        db, err := dao.NewStorage()        if err != nil {            w.Write([]byte(err.Error()))            w.WriteHeader(http.StatusBadRequest)            return        }        apps, err := service.NewBetterHandle(db).GetApps(args)        if err != nil {            w.Write([]byte(err.Error()))            w.WriteHeader(http.StatusBadRequest)            return        }        w.Write([]byte(apps))        w.WriteHeader(http.StatusOK)        return    })    err := http.ListenAndServe(":8080", nil)    if err != nil {        panic(err)    }}

service层

//better/service/better.gopackage serviceimport "errors"// better gotype betterHandle struct {    Storage BetterHandleStorage}type BetterHandleStorage interface {    GetApps() (string, error)}func NewBetterHandle(storage BetterHandleStorage) *betterHandle {    return &betterHandle{Storage: storage}}func (h betterHandle) GetApps(args string) (apps string, err error) {    if args == "" {        return "", errors.New("args is nil")    }    apps, err = h.Storage.GetApps()    if err != nil {        return "", err    }    return apps, nil}

单元测试

package serviceimport (    "testing")func Test_BetterGetApps(t *testing.T) {    var m DBMock    apps, err := NewBetterHandle(&m).GetApps("Test_BetterGetApps")    if err != nil {        t.Fatal("getApps err", err.Error())    }    t.Log("apps:", apps)}type DBMock struct {}// 构建mock数据// 这样我们就可以测试我们的方法,而不需要启动一个dbfunc (m *DBMock) GetApps() (string, error) {    return "mock apps", nil}

以上就是编写可测试的better go代码示例分析的全部内容了,更多与编写可测试的better go代码示例分析相关的内容可以搜索之前的文章或者浏览下面的文章进行学习哈!相信小编会给大家增添更多知识,希望大家能够支持一下!

测试 单元 服务 代码 数据 接口 数据库 方法 示例 可测 分析 内容 就是 文章 时候 更多 不错 普通 例子 功能 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网新科技 华服互联网科技靠谱吗 重生之互联网科技帝国 科技金融是不是互联网金融 互联网科技有限公司经营范围 互联网科技的 致骋互联网科技 浩特互联网科技 未来的互联网科技 青岛中康互联网医疗科技有限公司 欧洲十大科技互联网公司 承德科技产业互联网发展 互联网系的金融科技公司 北京市互联网新科技 福建互联网展示科技馆设计 湖北辰鑫科技互联网 互联网公司属于科技吗 互联网金融运营模式中的金融科技 亚光科技低轨卫星互联网 互联网科技大佬云集 深圳市人人互联网科技有限公司 苏州找大状互联网科技有限公司 互联网金融科技平台 承德科技产业互联网发展 晓花互联网科技有限公司网址 哈尔滨屹滨互联网科技有限公司 互联网方面的科技前沿 上海科技产业互联网平台 安徽零酒互联网科技有限公司 武汉亿视互联网科技有限公司
0