diff --git a/db/redis/client.go b/db/redis/client.go index 459d485..6946d67 100644 --- a/db/redis/client.go +++ b/db/redis/client.go @@ -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() diff --git a/go.mod b/go.mod index e98c6d1..28cc671 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index a9860ac..66e5118 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/proto/ss/grpc_pb/mocks/service_user_grpc.pb.go b/proto/ss/grpc_pb/mocks/service_user_grpc.pb.go new file mode 100644 index 0000000..3a71a9b --- /dev/null +++ b/proto/ss/grpc_pb/mocks/service_user_grpc.pb.go @@ -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)) +} diff --git a/utils/test.go b/utils/test.go new file mode 100644 index 0000000..2273ac5 --- /dev/null +++ b/utils/test.go @@ -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"]) +}