这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
测试
单元测试
文件定义规则
1、所有测试文件以 _test.go 结尾
2、方法名定义,func TestXxx(*testing.T)
3、初始化逻辑放到TestMain中,模板如下
func TestMain(m *testing.M) {
// 测试前: 数据装载、配置初始化等前置工作
code := m.Run()
// 测试后:释放资源等收尾工作
os.Exit(code)
}
覆盖率
代码覆盖率是检验一个代码单元测试的标准。
项目实战
分词结构
常用的三层结构模型
Gin简单使用
文档 | Gin Web Framework (gin-gonic.com)
RESTful风格
RESTful API 的规范建议我们使用特定的HTTP方法来对服务器上的资源进行操作。如:
- GET,表示读取服务器上的资源
- POST,表示在服务器上创建资源
- PUT,表示更新或者替换服务器上的资源
- DELETE,表示删除服务器上的资源
- PATCH,表示更新、修改资源的一部分
分组路由
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 分组路由
// 用户
user := r.Group("/user")
{
user.GET("/:id", func(context *gin.Context) {
msg := context.Param("id")
context.JSON(200, gin.H{"msg": msg})
})
user.GET("/find", func(context *gin.Context) {
context.JSON(200, "find")
})
}
// 订单
order := r.Group("/order")
{
order.GET("/:id", func(context *gin.Context) {
msg := context.Param("id")
context.JSON(200, gin.H{"msg": msg})
})
order.GET("/find", func(context *gin.Context) {
context.JSON(200, "find")
})
}
err := r.Run("localhost:8083")
if err != nil {
fmt.Println("运行失败。。", err)
}
}
优雅退出
在运行Web服务时,最近强制关闭或者关闭等情况,可以通过信号量对于代码进行优雅退出(即对于一些服务的善后)
func main() {
r := gin.Default()
go r.Run(":8080")
// 退出信号量的检测
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Println("退出后的一些相关逻辑的处理...")
}
Gin中间件的一些原理
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
func TokenRequired() gin.HandlerFunc {
return func(context *gin.Context) {
var token string
for k, v := range context.Request.Header {
// 需要用大写,使用x-token 不可
if k == "X-Token" {
token = v[0]
}
}
if token != "hsx" {
context.JSON(http.StatusUnauthorized, gin.H{
"msg": "未登录",
})
//return 不会阻止不访问下面的内容, 需要使用 context.Abort()
//return
context.Abort()
}
context.Next()
}
}
func main() {
r := gin.New()
r.Use(gin.Logger(), gin.Recovery())
r.Use(TokenRequired())
r.GET("/test", func(context *gin.Context) {
fmt.Println("业务逻辑...")
context.JSON(200, "data")
})
r.Run(":8080")
}
分析
底层的各个Handler,使用的是同级的一个数组存储,当你在当前的Auth使用了return,那么只是跳过了当前的Handler,还是会使用后面的Handler的。而context.Abort()则是直接控制index。所以能达到真正的结束效果。
编码规范
注解规范
参考文章:Go语言编码规范指导
goland 推荐 使用插件 Goanno,以及一些相关模块推荐
-
Normal Methood
// ${function_name} , ${todo} // @param // ${params} , ${todo} // @return // ${return_types} , ${todo} -
Interface
// ${interface_name} , ${todo}
- Struct
// ${struct_name} , ${todo}
总结
今天学习到了测试、初步的项目开发、编码规范这三个主要内容
-
对于测试。首先明白了go的单元测试与Java的不同之处,go对于一些文件的命名和方法的命名是存在规范需要去遵守的,这样才能进行单元测试。同时还是明白了测试的一项很重要的标准:代码覆盖率
-
对于项目的初步开发,首先我学习到了Gin框架的简单使用,我感觉最重要的一个部分还是Gin对于中间件的一些比较重要的原理,这能避免你踩到一些很严重的坑。也就是在中间件的退出,对于go的中间件,其实可以理解成一个过滤链。在使用过程中,若想跳过所有中间的调研,不能直接使用
return,这样只会跳过当前中间件,还会执行后面的中间件。此时需要使用context.Abort()才能达到要求 -
编码规范。若要编写一个高质量的代码,其中,注解的编写是必不可少