type相关
别名:本质上是更好的理解代码,比如byte(uint8)、rune(int32)
定义新类型,那么就相当于时struct了
package main
import (
"fmt"
"strconv"
)
// XInt 别名,在编译的时候会直接替换int
type XInt = int
// YInt 自定义类型,输出时不属于int类型,可以拓展int内置的方法
type YInt int
func (y YInt) toString() string {
return strconv.Itoa(int(y))
}
func main() {
// 别名,本质在编译替换int
var x1 XInt = 12
fmt.Printf("%T %v\n", x1, x1)
var x2 int = 22
fmt.Println(x1 + x2)
//基于int定义了新类型
var y1 YInt = 10
fmt.Printf("%T %v\n", y1, y1)
var y2 int = 12
fmt.Println(int(y1) + y2)
fmt.Println(y1.toString())
}
Go测试
单元测试
参考:单元测试 · Golang 学习笔记
单元测试 · Go语言中文文档
// 表驱动测试
func TestAdd(t *testing.T) {
type input struct {
a, b int
}
type want struct {
res int
}
var tests = []struct {
input
want
expression string
}{
{input{1, 3}, want{4}, "1+3"},
{input{2, 4}, want{6}, "2+4"},
}
for _, tt := range tests {
t.Run(tt.expression, func(t *testing.T) {
got := Add(tt.a, tt.b)
if got != tt.res {
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want.res)
}
})
}
}
参考:https://juejin.cn/post/7051101245309714440
go语言中自带轻量级别测试框架testing和自带的go test命令来实现单元测试和性能测试。
采用table_driven驱动来编写测试用例方便我们处理代码。
func TestRouter_match(T *testing.T) {
r := newRouter()
var mockHandler HandleFunc = func() {}
// 添加一些路由
r.AddRoute(http.MethodGet, "/user", mockHandler)
r.AddRoute(http.MethodGet, "/", mockHandler)
r.AddRoute(http.MethodGet, "/user/home", mockHandler)
r.AddRoute(http.MethodGet, "/order/detail", mockHandler)
r.AddRoute(http.MethodPost, "/order/create", mockHandler)
r.AddRoute(http.MethodPost, "/login", mockHandler)
r.AddRoute(http.MethodGet, "/index", mockHandler)
testCases := []struct {
name string
method string
path string
expected *node // 期望匹配的节点
}{
{"existing route", http.MethodGet, "/user", r.trees[http.MethodGet].children["user"]},
{"root route", http.MethodGet, "/", r.trees[http.MethodGet]},
{"nested route", http.MethodGet, "/user/home", r.trees[http.MethodGet].children["user"].children["home"]},
{"non-existing route", http.MethodGet, "/notfound", nil},
{"existing route with params", http.MethodGet, "/index", r.trees[http.MethodGet].children["index"]},
{"non-existing method", http.MethodPut, "/user", nil},
}
for _, tc := range testCases {
T.Run(tc.name, func(t *testing.T) {
actual := r.match(tc.method, tc.path)
if actual != tc.expected {
t.Errorf("expected %v, got %v", tc.expected, actual)
}
})
}
}
将我们的测试用例封装成[]struct并用循环,T.Run最终来进行批量处理。
todo:Mock、Stub、gomock、gomonkey。