feat 单元测试

This commit is contained in:
2026-01-05 00:32:24 +08:00
parent 3ea3a3ac6d
commit 6523820cf6
5 changed files with 229 additions and 4 deletions

View File

@@ -24,8 +24,10 @@ func Init(cfg *config.RedisConfig) error {
cli: client,
}
cacheInstance = &CacheClient{
cli: client,
logger: log.GetLogger().Named("CACHE"),
cli: client,
}
if logger := log.GetLogger(); logger != nil {
cacheInstance.logger = logger.Named("CACHE")
}
_, err := client.Ping(context.Background()).Result()

5
go.mod
View File

@@ -7,11 +7,13 @@ require (
github.com/gin-gonic/gin v1.11.0
github.com/gobwas/ws v1.4.0
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/golang/mock v1.6.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/panjf2000/gnet/v2 v2.9.7
github.com/redis/go-redis/v9 v9.10.0
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
go.etcd.io/etcd/api/v3 v3.6.1
go.etcd.io/etcd/client/v3 v3.6.1
go.mongodb.org/mongo-driver v1.17.6
@@ -32,6 +34,7 @@ require (
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
@@ -60,6 +63,7 @@ require (
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/panjf2000/ants/v2 v2.11.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
@@ -90,4 +94,5 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

11
go.sum
View File

@@ -66,6 +66,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
@@ -107,8 +109,6 @@ github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/panjf2000/ants/v2 v2.11.3 h1:AfI0ngBoXJmYOpDh9m516vjqoUu2sLrIVgppI9TZVpg=
github.com/panjf2000/ants/v2 v2.11.3/go.mod h1:8u92CYMUc6gyvTIw8Ru7Mt7+/ESnJahz5EVtqfrilek=
github.com/panjf2000/gnet/v2 v2.9.1 h1:bKewICy/0xnQ9PMzNaswpe/Ah14w1TrRk91LHTcbIlA=
github.com/panjf2000/gnet/v2 v2.9.1/go.mod h1:WQTxDWYuQ/hz3eccH0FN32IVuvZ19HewEWx0l62fx7E=
github.com/panjf2000/gnet/v2 v2.9.7 h1:6zW7Jl3oAfXwSuh1PxHLndoL2MQRWx0AJR6aaQjxUgA=
github.com/panjf2000/gnet/v2 v2.9.7/go.mod h1:WQTxDWYuQ/hz3eccH0FN32IVuvZ19HewEWx0l62fx7E=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
@@ -162,6 +162,7 @@ github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zU
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/etcd/api/v3 v3.6.1 h1:yJ9WlDih9HT457QPuHt/TH/XtsdN2tubyxyQHSHPsEo=
go.etcd.io/etcd/api/v3 v3.6.1/go.mod h1:lnfuqoGsXMlZdTJlact3IB56o3bWp1DIlXPIGKRArto=
@@ -203,6 +204,7 @@ golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
@@ -211,12 +213,14 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
@@ -224,6 +228,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -242,6 +248,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=

View File

@@ -0,0 +1,177 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./proto/ss/grpc_pb/service_user_grpc.pb.go
// Package mocks is a generated GoMock package.
package mocks
import (
grpc_pb "common/proto/ss/grpc_pb"
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
grpc "google.golang.org/grpc"
)
// MockUserClient is a mock of UserClient interface.
type MockUserClient struct {
ctrl *gomock.Controller
recorder *MockUserClientMockRecorder
}
// MockUserClientMockRecorder is the mock recorder for MockUserClient.
type MockUserClientMockRecorder struct {
mock *MockUserClient
}
// NewMockUserClient creates a new mock instance.
func NewMockUserClient(ctrl *gomock.Controller) *MockUserClient {
mock := &MockUserClient{ctrl: ctrl}
mock.recorder = &MockUserClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockUserClient) EXPECT() *MockUserClientMockRecorder {
return m.recorder
}
// GetUserInfo mocks base method.
func (m *MockUserClient) GetUserInfo(ctx context.Context, in *grpc_pb.GetUserInfoReq, opts ...grpc.CallOption) (*grpc_pb.GetUserInfoResp, error) {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetUserInfo", varargs...)
ret0, _ := ret[0].(*grpc_pb.GetUserInfoResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserInfo indicates an expected call of GetUserInfo.
func (mr *MockUserClientMockRecorder) GetUserInfo(ctx, in interface{}, opts ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserInfo", reflect.TypeOf((*MockUserClient)(nil).GetUserInfo), varargs...)
}
// Login mocks base method.
func (m *MockUserClient) Login(ctx context.Context, in *grpc_pb.LoginReq, opts ...grpc.CallOption) (*grpc_pb.LoginResp, error) {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Login", varargs...)
ret0, _ := ret[0].(*grpc_pb.LoginResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Login indicates an expected call of Login.
func (mr *MockUserClientMockRecorder) Login(ctx, in interface{}, opts ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Login", reflect.TypeOf((*MockUserClient)(nil).Login), varargs...)
}
// MockUserServer is a mock of UserServer interface.
type MockUserServer struct {
ctrl *gomock.Controller
recorder *MockUserServerMockRecorder
}
// MockUserServerMockRecorder is the mock recorder for MockUserServer.
type MockUserServerMockRecorder struct {
mock *MockUserServer
}
// NewMockUserServer creates a new mock instance.
func NewMockUserServer(ctrl *gomock.Controller) *MockUserServer {
mock := &MockUserServer{ctrl: ctrl}
mock.recorder = &MockUserServerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockUserServer) EXPECT() *MockUserServerMockRecorder {
return m.recorder
}
// GetUserInfo mocks base method.
func (m *MockUserServer) GetUserInfo(arg0 context.Context, arg1 *grpc_pb.GetUserInfoReq) (*grpc_pb.GetUserInfoResp, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserInfo", arg0, arg1)
ret0, _ := ret[0].(*grpc_pb.GetUserInfoResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserInfo indicates an expected call of GetUserInfo.
func (mr *MockUserServerMockRecorder) GetUserInfo(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserInfo", reflect.TypeOf((*MockUserServer)(nil).GetUserInfo), arg0, arg1)
}
// Login mocks base method.
func (m *MockUserServer) Login(arg0 context.Context, arg1 *grpc_pb.LoginReq) (*grpc_pb.LoginResp, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Login", arg0, arg1)
ret0, _ := ret[0].(*grpc_pb.LoginResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Login indicates an expected call of Login.
func (mr *MockUserServerMockRecorder) Login(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Login", reflect.TypeOf((*MockUserServer)(nil).Login), arg0, arg1)
}
// mustEmbedUnimplementedUserServer mocks base method.
func (m *MockUserServer) mustEmbedUnimplementedUserServer() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "mustEmbedUnimplementedUserServer")
}
// mustEmbedUnimplementedUserServer indicates an expected call of mustEmbedUnimplementedUserServer.
func (mr *MockUserServerMockRecorder) mustEmbedUnimplementedUserServer() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "mustEmbedUnimplementedUserServer", reflect.TypeOf((*MockUserServer)(nil).mustEmbedUnimplementedUserServer))
}
// MockUnsafeUserServer is a mock of UnsafeUserServer interface.
type MockUnsafeUserServer struct {
ctrl *gomock.Controller
recorder *MockUnsafeUserServerMockRecorder
}
// MockUnsafeUserServerMockRecorder is the mock recorder for MockUnsafeUserServer.
type MockUnsafeUserServerMockRecorder struct {
mock *MockUnsafeUserServer
}
// NewMockUnsafeUserServer creates a new mock instance.
func NewMockUnsafeUserServer(ctrl *gomock.Controller) *MockUnsafeUserServer {
mock := &MockUnsafeUserServer{ctrl: ctrl}
mock.recorder = &MockUnsafeUserServerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockUnsafeUserServer) EXPECT() *MockUnsafeUserServerMockRecorder {
return m.recorder
}
// mustEmbedUnimplementedUserServer mocks base method.
func (m *MockUnsafeUserServer) mustEmbedUnimplementedUserServer() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "mustEmbedUnimplementedUserServer")
}
// mustEmbedUnimplementedUserServer indicates an expected call of mustEmbedUnimplementedUserServer.
func (mr *MockUnsafeUserServerMockRecorder) mustEmbedUnimplementedUserServer() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "mustEmbedUnimplementedUserServer", reflect.TypeOf((*MockUnsafeUserServer)(nil).mustEmbedUnimplementedUserServer))
}

34
utils/test.go Normal file
View File

@@ -0,0 +1,34 @@
package utils
import (
"bytes"
"common/net/http/http_resp"
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/suite"
"net/http/httptest"
)
// 给测试用例提供一些通用函数
// CreateTestContext 创建测试用例的上下文
func CreateTestContext(method, path string, body interface{}) (*httptest.ResponseRecorder, *gin.Context) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
var buf bytes.Buffer
if body != nil {
_ = json.NewEncoder(&buf).Encode(body)
}
req := httptest.NewRequest(method, path, &buf)
req.Header.Set("Content-Type", "application/json")
c.Request = req
return w, c
}
// AssertResponse 断言返回值
func AssertResponse(ts *suite.Suite, w *httptest.ResponseRecorder, httpCode int, code *http_resp.Code) {
ts.Assert().Equal(httpCode, w.Code)
var response map[string]interface{}
ts.Assert().NoError(json.Unmarshal(w.Body.Bytes(), &response))
ts.Assert().Equal(float64(code.Code()), response["code"])
}