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

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

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

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

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

一个普通的例子

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

//better/main.gopackagemainimport("errors""net/http""better/service""github.com/jinzhu/gorm")funcmain(){http.HandleFunc("/bad",func(whttp.ResponseWriter,r*http.Request){args:=r.URL.Query().Get("args")//initdbdb,err:=dao.NewStorage()iferr!=nil{w.Write([]byte(err.Error()))w.WriteHeader(http.StatusBadRequest)return}apps,err:=service.NewHandle().GetApps(args,db.DB)iferr!=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)iferr!=nil{panic(err)}}

service层

//better/service/bad.gopackageserviceimport("errors""github.com/jinzhu/gorm")typehandlestruct{}funcNewHandle()*handle{return&handle{}}func(hhandle)GetApps(argsstring,db*gorm.DB)(appsstring,errerror){ifargs==""{return"",errors.New("argsisnil")}//引入dberr=db.Find(&apps).Erroriferr!=nil{return"",err}returnapps,nil}

数据库层

//better/dao/apps.gopackagedaoimport"github.com/jinzhu/gorm"typeStoragestruct{DB*gorm.DB}funcNewStorage()(*Storage,error){db,err:=gorm.Open("user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local")iferr!=nil{returnnil,err}return&Storage{DB:db},nil}func(s*Storage)GetApps()(string,error){return"daoapps",nil}

单元测试代码

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

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

一种更好的实现方式

新增一个better接口

//better/main.gopackagemainimport("net/http""better/dao""better/service""github.com/jinzhu/gorm")funcmain(){http.HandleFunc("/better",func(whttp.ResponseWriter,r*http.Request){args:=r.URL.Query().Get("args")//initdbdb,err:=dao.NewStorage()iferr!=nil{w.Write([]byte(err.Error()))w.WriteHeader(http.StatusBadRequest)return}apps,err:=service.NewBetterHandle(db).GetApps(args)iferr!=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)iferr!=nil{panic(err)}}

service层

//better/service/better.gopackageserviceimport"errors"//bettergotypebetterHandlestruct{StorageBetterHandleStorage}typeBetterHandleStorageinterface{GetApps()(string,error)}funcNewBetterHandle(storageBetterHandleStorage)*betterHandle{return&betterHandle{Storage:storage}}func(hbetterHandle)GetApps(argsstring)(appsstring,errerror){ifargs==""{return"",errors.New("argsisnil")}apps,err=h.Storage.GetApps()iferr!=nil{return"",err}returnapps,nil}

单元测试

packageserviceimport("testing")funcTest_BetterGetApps(t*testing.T){varmDBMockapps,err:=NewBetterHandle(&m).GetApps("Test_BetterGetApps")iferr!=nil{t.Fatal("getAppserr",err.Error())}t.Log("apps:",apps)}typeDBMockstruct{}//构建mock数据//这样我们就可以测试我们的方法,而不需要启动一个dbfunc(m*DBMock)GetApps()(string,error){return"mockapps",nil}

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

发布于 2022-01-17 21:58:39
收藏
分享
海报
0 条评论
41
上一篇:Go中如何通过Gob包序列化二进制数据 下一篇:CDH5报错Exhausted available authentication methods怎么办
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码