258 lines
5.8 KiB
Go
258 lines
5.8 KiB
Go
|
|
package model
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"errors"
|
|||
|
|
"testing"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// TestNewSuccessResponse 测试创建成功响应
|
|||
|
|
func TestNewSuccessResponse(t *testing.T) {
|
|||
|
|
tests := []struct {
|
|||
|
|
name string
|
|||
|
|
data interface{}
|
|||
|
|
}{
|
|||
|
|
{
|
|||
|
|
name: "字符串数据",
|
|||
|
|
data: "success",
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "map数据",
|
|||
|
|
data: map[string]string{
|
|||
|
|
"id": "1",
|
|||
|
|
"name": "test",
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "nil数据",
|
|||
|
|
data: nil,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "数组数据",
|
|||
|
|
data: []string{"a", "b", "c"},
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for _, tt := range tests {
|
|||
|
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
|
resp := NewSuccessResponse(tt.data)
|
|||
|
|
if resp == nil {
|
|||
|
|
t.Fatal("NewSuccessResponse() 返回nil")
|
|||
|
|
}
|
|||
|
|
if resp.Code != CodeSuccess {
|
|||
|
|
t.Errorf("Code = %d, want %d", resp.Code, CodeSuccess)
|
|||
|
|
}
|
|||
|
|
if resp.Message != MsgSuccess {
|
|||
|
|
t.Errorf("Message = %q, want %q", resp.Message, MsgSuccess)
|
|||
|
|
}
|
|||
|
|
// 对于可比较类型直接比较,对于不可比较类型只验证不为nil
|
|||
|
|
switch v := tt.data.(type) {
|
|||
|
|
case string, nil:
|
|||
|
|
// 数组不能直接比较,只验证不为nil
|
|||
|
|
if tt.data != nil && resp.Data == nil {
|
|||
|
|
t.Error("Data 不应为nil")
|
|||
|
|
}
|
|||
|
|
if tt.data == nil && resp.Data != nil {
|
|||
|
|
t.Error("Data 应为nil")
|
|||
|
|
}
|
|||
|
|
case []string:
|
|||
|
|
// 数组不能直接比较,只验证不为nil
|
|||
|
|
if resp.Data == nil {
|
|||
|
|
t.Error("Data 不应为nil")
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
// 对于map等不可比较类型,只验证不为nil
|
|||
|
|
if tt.data != nil && resp.Data == nil {
|
|||
|
|
t.Error("Data 不应为nil")
|
|||
|
|
}
|
|||
|
|
_ = v
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestNewErrorResponse 测试创建错误响应
|
|||
|
|
func TestNewErrorResponse(t *testing.T) {
|
|||
|
|
tests := []struct {
|
|||
|
|
name string
|
|||
|
|
code int
|
|||
|
|
message string
|
|||
|
|
err error
|
|||
|
|
}{
|
|||
|
|
{
|
|||
|
|
name: "带错误信息",
|
|||
|
|
code: CodeBadRequest,
|
|||
|
|
message: "请求参数错误",
|
|||
|
|
err: errors.New("具体错误信息"),
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "无错误信息",
|
|||
|
|
code: CodeUnauthorized,
|
|||
|
|
message: "未授权",
|
|||
|
|
err: nil,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "服务器错误",
|
|||
|
|
code: CodeServerError,
|
|||
|
|
message: "服务器内部错误",
|
|||
|
|
err: errors.New("数据库连接失败"),
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for _, tt := range tests {
|
|||
|
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
|
resp := NewErrorResponse(tt.code, tt.message, tt.err)
|
|||
|
|
if resp == nil {
|
|||
|
|
t.Fatal("NewErrorResponse() 返回nil")
|
|||
|
|
}
|
|||
|
|
if resp.Code != tt.code {
|
|||
|
|
t.Errorf("Code = %d, want %d", resp.Code, tt.code)
|
|||
|
|
}
|
|||
|
|
if resp.Message != tt.message {
|
|||
|
|
t.Errorf("Message = %q, want %q", resp.Message, tt.message)
|
|||
|
|
}
|
|||
|
|
if tt.err != nil {
|
|||
|
|
if resp.Error != tt.err.Error() {
|
|||
|
|
t.Errorf("Error = %q, want %q", resp.Error, tt.err.Error())
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if resp.Error != "" {
|
|||
|
|
t.Errorf("Error 应为空,实际为 %q", resp.Error)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestNewPaginationResponse 测试创建分页响应
|
|||
|
|
func TestNewPaginationResponse(t *testing.T) {
|
|||
|
|
tests := []struct {
|
|||
|
|
name string
|
|||
|
|
data interface{}
|
|||
|
|
total int64
|
|||
|
|
page int
|
|||
|
|
perPage int
|
|||
|
|
}{
|
|||
|
|
{
|
|||
|
|
name: "正常分页",
|
|||
|
|
data: []string{"a", "b", "c"},
|
|||
|
|
total: 100,
|
|||
|
|
page: 1,
|
|||
|
|
perPage: 20,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "空数据",
|
|||
|
|
data: []string{},
|
|||
|
|
total: 0,
|
|||
|
|
page: 1,
|
|||
|
|
perPage: 20,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "最后一页",
|
|||
|
|
data: []string{"a", "b"},
|
|||
|
|
total: 22,
|
|||
|
|
page: 3,
|
|||
|
|
perPage: 10,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for _, tt := range tests {
|
|||
|
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
|
resp := NewPaginationResponse(tt.data, tt.total, tt.page, tt.perPage)
|
|||
|
|
if resp == nil {
|
|||
|
|
t.Fatal("NewPaginationResponse() 返回nil")
|
|||
|
|
}
|
|||
|
|
if resp.Code != CodeSuccess {
|
|||
|
|
t.Errorf("Code = %d, want %d", resp.Code, CodeSuccess)
|
|||
|
|
}
|
|||
|
|
if resp.Message != MsgSuccess {
|
|||
|
|
t.Errorf("Message = %q, want %q", resp.Message, MsgSuccess)
|
|||
|
|
}
|
|||
|
|
// 对于可比较类型直接比较,对于不可比较类型只验证不为nil
|
|||
|
|
switch v := tt.data.(type) {
|
|||
|
|
case string, nil:
|
|||
|
|
// 数组不能直接比较,只验证不为nil
|
|||
|
|
if tt.data != nil && resp.Data == nil {
|
|||
|
|
t.Error("Data 不应为nil")
|
|||
|
|
}
|
|||
|
|
if tt.data == nil && resp.Data != nil {
|
|||
|
|
t.Error("Data 应为nil")
|
|||
|
|
}
|
|||
|
|
case []string:
|
|||
|
|
// 数组不能直接比较,只验证不为nil
|
|||
|
|
if resp.Data == nil {
|
|||
|
|
t.Error("Data 不应为nil")
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
// 对于map等不可比较类型,只验证不为nil
|
|||
|
|
if tt.data != nil && resp.Data == nil {
|
|||
|
|
t.Error("Data 不应为nil")
|
|||
|
|
}
|
|||
|
|
_ = v
|
|||
|
|
}
|
|||
|
|
if resp.Total != tt.total {
|
|||
|
|
t.Errorf("Total = %d, want %d", resp.Total, tt.total)
|
|||
|
|
}
|
|||
|
|
if resp.Page != tt.page {
|
|||
|
|
t.Errorf("Page = %d, want %d", resp.Page, tt.page)
|
|||
|
|
}
|
|||
|
|
if resp.PerPage != tt.perPage {
|
|||
|
|
t.Errorf("PerPage = %d, want %d", resp.PerPage, tt.perPage)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestResponseConstants 测试响应常量
|
|||
|
|
func TestResponseConstants(t *testing.T) {
|
|||
|
|
// 测试状态码常量
|
|||
|
|
statusCodes := map[string]int{
|
|||
|
|
"CodeSuccess": CodeSuccess,
|
|||
|
|
"CodeCreated": CodeCreated,
|
|||
|
|
"CodeBadRequest": CodeBadRequest,
|
|||
|
|
"CodeUnauthorized": CodeUnauthorized,
|
|||
|
|
"CodeForbidden": CodeForbidden,
|
|||
|
|
"CodeNotFound": CodeNotFound,
|
|||
|
|
"CodeConflict": CodeConflict,
|
|||
|
|
"CodeServerError": CodeServerError,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
expectedCodes := map[string]int{
|
|||
|
|
"CodeSuccess": 200,
|
|||
|
|
"CodeCreated": 201,
|
|||
|
|
"CodeBadRequest": 400,
|
|||
|
|
"CodeUnauthorized": 401,
|
|||
|
|
"CodeForbidden": 403,
|
|||
|
|
"CodeNotFound": 404,
|
|||
|
|
"CodeConflict": 409,
|
|||
|
|
"CodeServerError": 500,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for name, code := range statusCodes {
|
|||
|
|
expected := expectedCodes[name]
|
|||
|
|
if code != expected {
|
|||
|
|
t.Errorf("%s = %d, want %d", name, code, expected)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试消息常量不为空
|
|||
|
|
messages := []string{
|
|||
|
|
MsgSuccess,
|
|||
|
|
MsgCreated,
|
|||
|
|
MsgBadRequest,
|
|||
|
|
MsgUnauthorized,
|
|||
|
|
MsgForbidden,
|
|||
|
|
MsgNotFound,
|
|||
|
|
MsgConflict,
|
|||
|
|
MsgServerError,
|
|||
|
|
MsgInvalidToken,
|
|||
|
|
MsgTokenExpired,
|
|||
|
|
MsgInvalidCredentials,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for _, msg := range messages {
|
|||
|
|
if msg == "" {
|
|||
|
|
t.Error("响应消息常量不应为空")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|