15 changed files with 2976 additions and 2 deletions
@ -0,0 +1,274 @@ |
|||||
|
package profile |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"crypto/md5" |
||||
|
"fmt" |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used
|
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.ChangePasswordRequest{} |
||||
|
|
||||
|
// TestChangePassword_Success 测试成功修改密码
|
||||
|
func TestChangePassword_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户,密码为 "password"
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 200, resp.Code) |
||||
|
assert.Equal(t, "修改密码成功", resp.Message) |
||||
|
|
||||
|
// 验证数据库中的密码已更新
|
||||
|
updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
newEncrypted := fmt.Sprintf("%x", md5.Sum([]byte(req.NewPassword))) |
||||
|
assert.Equal(t, newEncrypted, updatedUser.Password) |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_WrongOldPassword 测试旧密码错误
|
||||
|
func TestChangePassword_WrongOldPassword(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据 - 使用错误的旧密码
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "wrongpassword", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 400, resp.Code) |
||||
|
assert.Equal(t, "旧密码错误", resp.Message) |
||||
|
|
||||
|
// 验证数据库中的密码没有改变
|
||||
|
updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, user.Password, updatedUser.Password) |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_NoUserIdInContext 测试上下文中没有用户ID
|
||||
|
func TestChangePassword_NoUserIdInContext(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,不包含用户ID
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "未获取到用户信息") |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_InvalidUserIdType 测试用户ID类型错误
|
||||
|
func TestChangePassword_InvalidUserIdType(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,用户ID类型错误
|
||||
|
ctx := context.WithValue(context.Background(), "userId", "invalid") |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户ID格式错误") |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_UserNotFound 测试用户不存在
|
||||
|
func TestChangePassword_UserNotFound(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 设置上下文,使用不存在的用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", int64(99999)) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_SamePassword 测试使用相同的新密码
|
||||
|
func TestChangePassword_SamePassword(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据 - 新密码与旧密码相同
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "password", |
||||
|
} |
||||
|
|
||||
|
// 执行测试 - 虽然相同,但从逻辑上应该允许
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 200, resp.Code) |
||||
|
|
||||
|
// 验证密码加密后的值仍然一致
|
||||
|
updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, user.Password, updatedUser.Password) |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_MultipleChanges 测试多次修改密码
|
||||
|
func TestChangePassword_MultipleChanges(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
passwords := []string{"password", "newpass1", "newpass2", "newpass3"} |
||||
|
|
||||
|
for i := 0; i < len(passwords)-1; i++ { |
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: passwords[i], |
||||
|
NewPassword: passwords[i+1], |
||||
|
} |
||||
|
|
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
require.NoError(t, err, "Failed at iteration %d", i) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 200, resp.Code) |
||||
|
|
||||
|
// 验证密码已更新
|
||||
|
updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
expectedEncrypted := fmt.Sprintf("%x", md5.Sum([]byte(passwords[i+1]))) |
||||
|
assert.Equal(t, expectedEncrypted, updatedUser.Password) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// BenchmarkChangePassword 性能测试
|
||||
|
func BenchmarkChangePassword(b *testing.B) { |
||||
|
svcCtx, _ := setupTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(&testing.T{}, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 准备修改密码请求数据
|
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
_, _ = logic.ChangePassword(req) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,243 @@ |
|||||
|
package profile |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
"gorm.io/driver/mysql" |
||||
|
"gorm.io/gorm" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used
|
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.GetProfileResponse{} |
||||
|
|
||||
|
// setupTestDB 创建测试数据库并返回 ServiceContext(使用MySQL)
|
||||
|
func setupTestDB(t *testing.T) (*svc.ServiceContext, func()) { |
||||
|
t.Helper() |
||||
|
|
||||
|
// 使用 MySQL 进行测试
|
||||
|
dsn := "root:dev123456@tcp(219.159.132.177:17173)/base?charset=utf8mb4&parseTime=true&loc=Local" |
||||
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 自动迁移表
|
||||
|
err = db.AutoMigrate(&model.User{}, &model.Profile{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 清理所有测试数据(使用 TRUNCATE 快速清空表)
|
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 0") |
||||
|
db.Exec("TRUNCATE TABLE profile") |
||||
|
db.Exec("TRUNCATE TABLE user") |
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 1") |
||||
|
|
||||
|
// 创建测试 ServiceContext
|
||||
|
svcCtx := &svc.ServiceContext{ |
||||
|
DB: db, |
||||
|
} |
||||
|
|
||||
|
// 清理函数
|
||||
|
cleanup := func() { |
||||
|
sqlDB, _ := db.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return svcCtx, cleanup |
||||
|
} |
||||
|
|
||||
|
// createTestUser 创建测试用户
|
||||
|
func createTestUser(t *testing.T, db *gorm.DB) *model.User { |
||||
|
t.Helper() |
||||
|
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "5f4dcc3b5aa765d61d8327deb882cf99", // MD5 of "password"
|
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
return user |
||||
|
} |
||||
|
|
||||
|
// createTestProfile 创建测试个人资料
|
||||
|
func createTestProfile(t *testing.T, db *gorm.DB, userId int64) *model.Profile { |
||||
|
t.Helper() |
||||
|
|
||||
|
now := time.Now() |
||||
|
profile := &model.Profile{ |
||||
|
UserId: userId, |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "This is a test bio", |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(profile).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
return profile |
||||
|
} |
||||
|
|
||||
|
// TestGetProfile_Success 测试成功获取个人信息
|
||||
|
func TestGetProfile_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
createTestProfile(t, svcCtx.DB, user.Id) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetProfile() |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
assert.Equal(t, "13800138000", resp.Phone) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", resp.Avatar) |
||||
|
assert.Equal(t, "This is a test bio", resp.Bio) |
||||
|
assert.Equal(t, 1, resp.Status) |
||||
|
} |
||||
|
|
||||
|
// TestGetProfile_NoProfile 测试用户没有个人资料的情况
|
||||
|
func TestGetProfile_NoProfile(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户,不创建个人资料
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetProfile() |
||||
|
|
||||
|
// 验证结果 - 应该返回用户信息,但 profile 字段为空
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "", resp.Avatar) |
||||
|
assert.Equal(t, "", resp.Bio) |
||||
|
} |
||||
|
|
||||
|
// TestGetProfile_NoUserIdInContext 测试上下文中没有用户ID
|
||||
|
func TestGetProfile_NoUserIdInContext(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,不包含用户ID
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetProfile() |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "未获取到用户信息") |
||||
|
} |
||||
|
|
||||
|
// TestGetProfile_InvalidUserIdType 测试用户ID类型错误
|
||||
|
func TestGetProfile_InvalidUserIdType(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,用户ID类型错误
|
||||
|
ctx := context.WithValue(context.Background(), "userId", "invalid") |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetProfile() |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户ID格式错误") |
||||
|
} |
||||
|
|
||||
|
// TestGetProfile_UserNotFound 测试用户不存在
|
||||
|
func TestGetProfile_UserNotFound(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 设置上下文,使用不存在的用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", int64(99999)) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetProfile() |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// BenchmarkGetProfile 性能测试
|
||||
|
func BenchmarkGetProfile(b *testing.B) { |
||||
|
svcCtx, _ := setupTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(&testing.T{}, svcCtx.DB) |
||||
|
createTestProfile(&testing.T{}, svcCtx.DB, user.Id) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
_, _ = logic.GetProfile() |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,269 @@ |
|||||
|
package profile |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used
|
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.UpdateProfileRequest{} |
||||
|
|
||||
|
// TestUpdateProfile_Success 测试成功更新个人资料
|
||||
|
func TestUpdateProfile_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Username: "updateduser", |
||||
|
Phone: "13900139000", |
||||
|
Avatar: "http://example.com/newavatar.jpg", |
||||
|
Bio: "Updated bio text", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "updateduser", resp.Username) |
||||
|
assert.Equal(t, "13900139000", resp.Phone) |
||||
|
assert.Equal(t, "http://example.com/newavatar.jpg", resp.Avatar) |
||||
|
assert.Equal(t, "Updated bio text", resp.Bio) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_CreateNewProfile 测试用户第一次更新时创建个人资料
|
||||
|
func TestUpdateProfile_CreateNewProfile(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户,但不创建个人资料
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "First bio", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", resp.Avatar) |
||||
|
assert.Equal(t, "First bio", resp.Bio) |
||||
|
|
||||
|
// 验证数据库中确实创建了个人资料
|
||||
|
profile, err := model.FindProfileByUserId(context.Background(), svcCtx.DB, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, profile) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", profile.Avatar) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_UpdateExistingProfile 测试更新已存在的个人资料
|
||||
|
func TestUpdateProfile_UpdateExistingProfile(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户和个人资料
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
createTestProfile(t, svcCtx.DB, user.Id) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据 - 只更新部分字段
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Bio: "Updated bio only", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, "Updated bio only", resp.Bio) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", resp.Avatar) // 保持不变
|
||||
|
|
||||
|
// 验证数据库中确实更新了
|
||||
|
profile, err := model.FindProfileByUserId(context.Background(), svcCtx.DB, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "Updated bio only", profile.Bio) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", profile.Avatar) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_UpdateOnlyUsername 测试只更新用户名
|
||||
|
func TestUpdateProfile_UpdateOnlyUsername(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据 - 只更新用户名
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Username: "newusername", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, "newusername", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) // 保持不变
|
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_NoUserIdInContext 测试上下文中没有用户ID
|
||||
|
func TestUpdateProfile_NoUserIdInContext(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,不包含用户ID
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Username: "updateduser", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "未获取到用户信息") |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_UserNotFound 测试用户不存在
|
||||
|
func TestUpdateProfile_UserNotFound(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 设置上下文,使用不存在的用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", int64(99999)) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Username: "updateduser", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_EmptyRequest 测试空请求
|
||||
|
func TestUpdateProfile_EmptyRequest(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备空请求数据
|
||||
|
req := &types.UpdateProfileRequest{} |
||||
|
|
||||
|
// 执行测试 - 应该正常工作,只是不做任何更新
|
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
// 验证数据没有变化
|
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "13800138000", resp.Phone) |
||||
|
} |
||||
|
|
||||
|
// BenchmarkUpdateProfile 性能测试
|
||||
|
func BenchmarkUpdateProfile(b *testing.B) { |
||||
|
svcCtx, _ := setupTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUser(&testing.T{}, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID
|
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 准备更新请求数据
|
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Username: "updateduser", |
||||
|
Bio: "Updated bio", |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
_, _ = logic.UpdateProfile(req) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,238 @@ |
|||||
|
package user |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
"gorm.io/driver/mysql" |
||||
|
"gorm.io/gorm" |
||||
|
) |
||||
|
|
||||
|
// setupUserTestDB 创建测试数据库并返回 ServiceContext(使用MySQL)
|
||||
|
func setupUserTestDB(t *testing.T) (*svc.ServiceContext, func()) { |
||||
|
t.Helper() |
||||
|
|
||||
|
// 使用 MySQL 进行测试
|
||||
|
dsn := "root:dev123456@tcp(219.159.132.177:17173)/base?charset=utf8mb4&parseTime=true&loc=Local" |
||||
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 自动迁移表
|
||||
|
err = db.AutoMigrate(&model.User{}, &model.Profile{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 清理所有测试数据(使用 TRUNCATE 快速清空表)
|
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 0") |
||||
|
db.Exec("TRUNCATE TABLE profile") |
||||
|
db.Exec("TRUNCATE TABLE user") |
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 1") |
||||
|
|
||||
|
// 创建测试 ServiceContext
|
||||
|
svcCtx := &svc.ServiceContext{ |
||||
|
DB: db, |
||||
|
} |
||||
|
|
||||
|
// 清理函数
|
||||
|
cleanup := func() { |
||||
|
sqlDB, _ := db.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return svcCtx, cleanup |
||||
|
} |
||||
|
|
||||
|
// TestCreateUser_Success 测试成功创建用户
|
||||
|
func TestCreateUser_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备创建用户请求数据
|
||||
|
req := &types.CreateUserRequest{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "password123", |
||||
|
Phone: "13800138000", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.CreateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Greater(t, resp.Id, int64(0)) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
assert.Equal(t, "13800138000", resp.Phone) |
||||
|
assert.Equal(t, 1, resp.Status) |
||||
|
assert.NotEmpty(t, resp.CreatedAt) |
||||
|
assert.NotEmpty(t, resp.UpdatedAt) |
||||
|
} |
||||
|
|
||||
|
// TestCreateUser_DuplicateEmail 测试邮箱重复
|
||||
|
func TestCreateUser_DuplicateEmail(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建第一个用户
|
||||
|
ctx := context.Background() |
||||
|
logic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
req1 := &types.CreateUserRequest{ |
||||
|
Username: "user1", |
||||
|
Email: "test@example.com", |
||||
|
Password: "password123", |
||||
|
} |
||||
|
|
||||
|
_, err := logic.CreateUser(req1) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 尝试创建相同邮箱的第二个用户
|
||||
|
logic2 := NewCreateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
req2 := &types.CreateUserRequest{ |
||||
|
Username: "user2", |
||||
|
Email: "test@example.com", // 相同邮箱
|
||||
|
Password: "password456", |
||||
|
} |
||||
|
|
||||
|
resp, err := logic2.CreateUser(req2) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "邮箱已被注册") |
||||
|
} |
||||
|
|
||||
|
// TestCreateUser_MinimumFields 测试使用最少字段创建用户
|
||||
|
func TestCreateUser_MinimumFields(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备创建用户请求数据 - 只填必填字段
|
||||
|
req := &types.CreateUserRequest{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "password123", |
||||
|
// Phone 字段可选,不填写
|
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.CreateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
assert.Equal(t, "", resp.Phone) // Phone 应该为空字符串
|
||||
|
} |
||||
|
|
||||
|
// TestCreateUser_PasswordEncryption 测试密码是否正确加密
|
||||
|
func TestCreateUser_PasswordEncryption(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
req := &types.CreateUserRequest{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "password123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.CreateUser(req) |
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
// 查询数据库验证密码已加密(不应该存储明文)
|
||||
|
user, err := model.FindOne(context.Background(), svcCtx.DB, resp.Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.NotEqual(t, "password123", user.Password) // 密码应该已被加密
|
||||
|
} |
||||
|
|
||||
|
// TestCreateUser_MultipleUsers 测试创建多个用户
|
||||
|
func TestCreateUser_MultipleUsers(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建多个用户
|
||||
|
users := []struct { |
||||
|
username string |
||||
|
email string |
||||
|
}{ |
||||
|
{"user1", "user1@example.com"}, |
||||
|
{"user2", "user2@example.com"}, |
||||
|
{"user3", "user3@example.com"}, |
||||
|
} |
||||
|
|
||||
|
for _, u := range users { |
||||
|
logic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
req := &types.CreateUserRequest{ |
||||
|
Username: u.username, |
||||
|
Email: u.email, |
||||
|
Password: "password123", |
||||
|
} |
||||
|
|
||||
|
resp, err := logic.CreateUser(req) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, u.username, resp.Username) |
||||
|
assert.Equal(t, u.email, resp.Email) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// BenchmarkCreateUser 性能测试
|
||||
|
func BenchmarkCreateUser(b *testing.B) { |
||||
|
svcCtx, _ := setupUserTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
req := &types.CreateUserRequest{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "password123", |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
// 使用不同的邮箱避免重复
|
||||
|
req.Email = "test@example.com" |
||||
|
logic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
_, _ = logic.CreateUser(req) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,332 @@ |
|||||
|
package user |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used
|
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.DeleteUserRequest{} |
||||
|
|
||||
|
// TestDeleteUser_Success 测试成功删除用户
|
||||
|
func TestDeleteUser_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
userId := user.Id |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备删除请求
|
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: userId, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.DeleteUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 200, resp.Code) |
||||
|
assert.Equal(t, "删除成功", resp.Message) |
||||
|
assert.True(t, resp.Success) |
||||
|
|
||||
|
// 验证用户已被删除
|
||||
|
_, err = model.FindOne(context.Background(), svcCtx.DB, userId) |
||||
|
require.Error(t, err) |
||||
|
assert.Equal(t, model.ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser_NotFound 测试删除不存在的用户
|
||||
|
func TestDeleteUser_NotFound(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用不存在的用户ID
|
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: 99999, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.DeleteUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回响应但用户不存在
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 404, resp.Code) |
||||
|
assert.Equal(t, "用户不存在", resp.Message) |
||||
|
assert.False(t, resp.Success) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser_NegativeId 测试使用负数ID删除
|
||||
|
func TestDeleteUser_NegativeId(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用负数ID
|
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: -1, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.DeleteUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回响应但用户不存在
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 404, resp.Code) |
||||
|
assert.Equal(t, "用户不存在", resp.Message) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser_ZeroId 测试使用零ID删除
|
||||
|
func TestDeleteUser_ZeroId(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用零ID
|
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: 0, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.DeleteUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回响应但用户不存在
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 404, resp.Code) |
||||
|
assert.Equal(t, "用户不存在", resp.Message) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser_ThenRecreate 测试删除后重建用户
|
||||
|
func TestDeleteUser_ThenRecreate(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
oldUserId := user.Id |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 删除用户
|
||||
|
logic1 := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
req1 := &types.DeleteUserRequest{ |
||||
|
Id: oldUserId, |
||||
|
} |
||||
|
|
||||
|
_, err = logic1.DeleteUser(req1) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 重建用户(使用相同的邮箱)
|
||||
|
createLogic := NewCreateUserLogic(ctx, svcCtx) |
||||
|
createReq := &types.CreateUserRequest{ |
||||
|
Username: "testuser2", |
||||
|
Email: "test@example.com", |
||||
|
Password: "newpassword", |
||||
|
} |
||||
|
|
||||
|
newUser, err := createLogic.CreateUser(createReq) |
||||
|
|
||||
|
// 验证结果 - 新用户ID应该不同
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, newUser) |
||||
|
assert.NotEqual(t, oldUserId, newUser.Id) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser_DeletedTwice 测试重复删除同一个用户
|
||||
|
func TestDeleteUser_DeletedTwice(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
userId := user.Id |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 第一次删除
|
||||
|
logic1 := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: userId, |
||||
|
} |
||||
|
|
||||
|
resp1, err := logic1.DeleteUser(req) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, 200, resp1.Code) |
||||
|
|
||||
|
// 第二次删除(应该返回404)
|
||||
|
logic2 := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
resp2, err := logic2.DeleteUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp2) |
||||
|
assert.Equal(t, 404, resp2.Code) |
||||
|
assert.Equal(t, "用户不存在", resp2.Message) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser_WithProfile 测试删除带个人资料的用户
|
||||
|
func TestDeleteUser_WithProfile(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
userId := user.Id |
||||
|
|
||||
|
// 创建个人资料
|
||||
|
profile := &model.Profile{ |
||||
|
UserId: userId, |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "Test bio", |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err = svcCtx.DB.Create(profile).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 删除用户
|
||||
|
ctx := context.Background() |
||||
|
logic := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: userId, |
||||
|
} |
||||
|
|
||||
|
resp, err := logic.DeleteUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, 200, resp.Code) |
||||
|
|
||||
|
// 验证用户和资料都已删除(或用户被删除后,profile变成孤数据)
|
||||
|
_, err = model.FindOne(context.Background(), svcCtx.DB, userId) |
||||
|
assert.Error(t, err) |
||||
|
assert.Equal(t, model.ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// BenchmarkDeleteUser 性能测试
|
||||
|
func BenchmarkDeleteUser(b *testing.B) { |
||||
|
svcCtx, _ := setupUserTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
// 为每次迭代创建用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
logic := NewDeleteUserLogic(ctx, svcCtx) |
||||
|
req := &types.DeleteUserRequest{ |
||||
|
Id: user.Id, |
||||
|
} |
||||
|
|
||||
|
_, _ = logic.DeleteUser(req) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,256 @@ |
|||||
|
package user |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used
|
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.GetUserRequest{} |
||||
|
|
||||
|
// TestGetUser_Success 测试成功获取用户
|
||||
|
func TestGetUser_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备获取用户请求数据
|
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: user.Id, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
assert.Equal(t, "13800138000", resp.Phone) |
||||
|
assert.Equal(t, 1, resp.Status) |
||||
|
} |
||||
|
|
||||
|
// TestGetUser_NotFound 测试用户不存在
|
||||
|
func TestGetUser_NotFound(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用不存在的用户ID
|
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: 99999, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// TestGetUser_NegativeId 测试使用负数ID
|
||||
|
func TestGetUser_NegativeId(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用负数ID
|
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: -1, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// TestGetUser_ZeroId 测试使用零ID
|
||||
|
func TestGetUser_ZeroId(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用零ID
|
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: 0, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// TestGetUser_UserWithEmptyPhone 测试获取没有手机号的用户
|
||||
|
func TestGetUser_UserWithEmptyPhone(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户,手机号为空
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备获取用户请求数据
|
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: user.Id, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, "", resp.Phone) |
||||
|
} |
||||
|
|
||||
|
// TestGetUser_DisabledUser 测试获取禁用状态的用户
|
||||
|
func TestGetUser_DisabledUser(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户,状态为禁用
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "disableduser", |
||||
|
Email: "disabled@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 2, // 禁用状态
|
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备获取用户请求数据
|
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: user.Id, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.GetUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 2, resp.Status) |
||||
|
} |
||||
|
|
||||
|
// BenchmarkGetUser 性能测试
|
||||
|
func BenchmarkGetUser(b *testing.B) { |
||||
|
svcCtx, _ := setupUserTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
req := &types.GetUserRequest{ |
||||
|
Id: user.Id, |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
logic := NewGetUserLogic(ctx, svcCtx) |
||||
|
_, _ = logic.GetUser(req) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,405 @@ |
|||||
|
package user |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used
|
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.UpdateUserRequest{} |
||||
|
|
||||
|
// TestUpdateUser_Success 测试成功更新用户
|
||||
|
func TestUpdateUser_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "olduser", |
||||
|
Email: "old@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Username: "newuser", |
||||
|
Email: "new@example.com", |
||||
|
Phone: "13900139000", |
||||
|
Status: 2, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "newuser", resp.Username) |
||||
|
assert.Equal(t, "new@example.com", resp.Email) |
||||
|
assert.Equal(t, "13900139000", resp.Phone) |
||||
|
assert.Equal(t, 2, resp.Status) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_OnlyUsername 测试只更新用户名
|
||||
|
func TestUpdateUser_OnlyUsername(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "olduser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据 - 只更新用户名
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Username: "newuser", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, "newuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) // 保持不变
|
||||
|
assert.Equal(t, "13800138000", resp.Phone) // 保持不变
|
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_OnlyEmail 测试只更新邮箱
|
||||
|
func TestUpdateUser_OnlyEmail(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "old@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据 - 只更新邮箱
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Email: "new@example.com", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, "new@example.com", resp.Email) |
||||
|
assert.Equal(t, "testuser", resp.Username) // 保持不变
|
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_DuplicateEmail 测试使用重复的邮箱
|
||||
|
func TestUpdateUser_DuplicateEmail(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建两个测试用户
|
||||
|
now := time.Now() |
||||
|
user1 := &model.User{ |
||||
|
Username: "user1", |
||||
|
Email: "user1@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
user2 := &model.User{ |
||||
|
Username: "user2", |
||||
|
Email: "user2@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user1).Error |
||||
|
require.NoError(t, err) |
||||
|
err = svcCtx.DB.Create(user2).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 尝试将 user1 的邮箱更新为 user2 的邮箱
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user1.Id, |
||||
|
Email: "user2@example.com", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "邮箱已被使用") |
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_SameEmail 测试使用相同的邮箱(应该允许)
|
||||
|
func TestUpdateUser_SameEmail(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用相同的邮箱
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Email: "test@example.com", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该成功
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_NotFound 测试更新不存在的用户
|
||||
|
func TestUpdateUser_NotFound(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 使用不存在的用户ID
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: 99999, |
||||
|
Username: "newuser", |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, resp) |
||||
|
assert.Contains(t, err.Error(), "用户不存在") |
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_EmptyRequest 测试空请求
|
||||
|
func TestUpdateUser_EmptyRequest(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 空请求
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
} |
||||
|
|
||||
|
// 执行测试 - 应该成功,只是不做任何更新
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser_ChangeStatus 测试修改用户状态
|
||||
|
func TestUpdateUser_ChangeStatus(t *testing.T) { |
||||
|
svcCtx, cleanup := setupUserTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建上下文
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建 Logic 实例
|
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 禁用用户
|
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Status: 2, |
||||
|
} |
||||
|
|
||||
|
// 执行测试
|
||||
|
resp, err := logic.UpdateUser(req) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 2, resp.Status) |
||||
|
|
||||
|
// 再次启用用户
|
||||
|
logic2 := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
req2 := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Status: 1, |
||||
|
} |
||||
|
|
||||
|
resp2, err := logic2.UpdateUser(req2) |
||||
|
|
||||
|
// 验证结果
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp2) |
||||
|
assert.Equal(t, 1, resp2.Status) |
||||
|
} |
||||
|
|
||||
|
// BenchmarkUpdateUser 性能测试
|
||||
|
func BenchmarkUpdateUser(b *testing.B) { |
||||
|
svcCtx, _ := setupUserTestDB(&testing.T{}) |
||||
|
defer func() { |
||||
|
sqlDB, _ := svcCtx.DB.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
}() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := svcCtx.DB.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
req := &types.UpdateUserRequest{ |
||||
|
Id: user.Id, |
||||
|
Username: "newuser", |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
logic := NewUpdateUserLogic(ctx, svcCtx) |
||||
|
_, _ = logic.UpdateUser(req) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,408 @@ |
|||||
|
package model |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
"gorm.io/driver/mysql" |
||||
|
"gorm.io/gorm" |
||||
|
) |
||||
|
|
||||
|
// setupProfileModelTestDB 创建测试数据库(使用MySQL)
|
||||
|
func setupProfileModelTestDB(t *testing.T) *gorm.DB { |
||||
|
t.Helper() |
||||
|
|
||||
|
// 使用 MySQL 进行测试
|
||||
|
dsn := "root:dev123456@tcp(219.159.132.177:17173)/base?charset=utf8mb4&parseTime=true&loc=Local" |
||||
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
err = db.AutoMigrate(&User{}, &Profile{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 清理所有测试数据(TRUNCATE)
|
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 0") |
||||
|
db.Exec("TRUNCATE TABLE profile") |
||||
|
db.Exec("TRUNCATE TABLE user") |
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 1") |
||||
|
|
||||
|
return db |
||||
|
} |
||||
|
|
||||
|
// createTestUserProfile 创建测试用户和关联的个人资料
|
||||
|
func createTestUserProfile(t *testing.T, db *gorm.DB) (int64, int64) { |
||||
|
t.Helper() |
||||
|
|
||||
|
now := time.Now() |
||||
|
|
||||
|
// 创建用户
|
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建个人资料
|
||||
|
profile := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "Test bio", |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err = db.Create(profile).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
return user.Id, profile.Id |
||||
|
} |
||||
|
|
||||
|
// TestInsertProfile 测试插入个人资料
|
||||
|
func TestInsertProfile(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 先创建用户
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建个人资料
|
||||
|
profile := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "Test bio", |
||||
|
} |
||||
|
|
||||
|
id, err := InsertProfile(ctx, db, profile) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Greater(t, id, int64(0)) |
||||
|
assert.Equal(t, id, profile.Id) |
||||
|
|
||||
|
// 验证数据已保存
|
||||
|
saved, err := FindOneProfile(ctx, db, id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", saved.Avatar) |
||||
|
assert.Equal(t, "Test bio", saved.Bio) |
||||
|
} |
||||
|
|
||||
|
// TestFindOneProfile 测试根据ID查询个人资料
|
||||
|
func TestFindOneProfile(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
_, profileId := createTestUserProfile(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 查询个人资料
|
||||
|
found, err := FindOneProfile(ctx, db, profileId) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, found) |
||||
|
assert.Equal(t, profileId, found.Id) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", found.Avatar) |
||||
|
assert.Equal(t, "Test bio", found.Bio) |
||||
|
} |
||||
|
|
||||
|
// TestFindOneProfile_NotFound 测试查询不存在的个人资料
|
||||
|
func TestFindOneProfile_NotFound(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
found, err := FindOneProfile(ctx, db, 99999) |
||||
|
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, found) |
||||
|
assert.Equal(t, ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestFindProfileByUserId 测试根据用户ID查询个人资料
|
||||
|
func TestFindProfileByUserId(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
userId, _ := createTestUserProfile(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 根据用户ID查询
|
||||
|
found, err := FindProfileByUserId(ctx, db, userId) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, found) |
||||
|
assert.Equal(t, userId, found.UserId) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", found.Avatar) |
||||
|
} |
||||
|
|
||||
|
// TestFindProfileByUserId_NotFound 测试查询不存在的用户个人资料
|
||||
|
func TestFindProfileByUserId_NotFound(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
found, err := FindProfileByUserId(ctx, db, 99999) |
||||
|
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, found) |
||||
|
assert.Equal(t, ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile 测试更新个人资料
|
||||
|
func TestUpdateProfile(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
_, profileId := createTestUserProfile(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 获取个人资料
|
||||
|
profile, err := FindOneProfile(ctx, db, profileId) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 修改数据
|
||||
|
profile.Avatar = "http://example.com/newavatar.jpg" |
||||
|
profile.Bio = "Updated bio" |
||||
|
|
||||
|
// 更新
|
||||
|
err = UpdateProfile(ctx, db, profile) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 验证更新结果
|
||||
|
updated, err := FindOneProfile(ctx, db, profileId) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "http://example.com/newavatar.jpg", updated.Avatar) |
||||
|
assert.Equal(t, "Updated bio", updated.Bio) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteProfile 测试删除个人资料
|
||||
|
func TestDeleteProfile(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
|
||||
|
_, profileId := createTestUserProfile(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 删除个人资料
|
||||
|
err := DeleteProfile(ctx, db, profileId) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 验证个人资料已被删除
|
||||
|
_, err = FindOneProfile(ctx, db, profileId) |
||||
|
require.Error(t, err) |
||||
|
assert.Equal(t, ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestProfile_UserProfileRelation 测试用户与个人资料的关联
|
||||
|
func TestProfile_UserProfileRelation(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建多个用户
|
||||
|
now := time.Now() |
||||
|
users := []User{ |
||||
|
{Username: "user1", Email: "user1@example.com", Password: "pass", Status: 1, CreatedAt: now, UpdatedAt: now}, |
||||
|
{Username: "user2", Email: "user2@example.com", Password: "pass", Status: 1, CreatedAt: now, UpdatedAt: now}, |
||||
|
{Username: "user3", Email: "user3@example.com", Password: "pass", Status: 1, CreatedAt: now, UpdatedAt: now}, |
||||
|
} |
||||
|
|
||||
|
for _, u := range users { |
||||
|
err := db.Create(&u).Error |
||||
|
require.NoError(t, err) |
||||
|
} |
||||
|
|
||||
|
// 只为 user1 和 user2 创建个人资料
|
||||
|
profile1 := &Profile{UserId: users[0].Id, Avatar: "avatar1.jpg", Bio: "Bio 1", CreatedAt: now, UpdatedAt: now} |
||||
|
profile2 := &Profile{UserId: users[1].Id, Avatar: "avatar2.jpg", Bio: "Bio 2", CreatedAt: now, UpdatedAt: now} |
||||
|
|
||||
|
err := db.Create(profile1).Error |
||||
|
require.NoError(t, err) |
||||
|
err = db.Create(profile2).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 验证 user1 有个人资料
|
||||
|
found1, err := FindProfileByUserId(ctx, db, users[0].Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "avatar1.jpg", found1.Avatar) |
||||
|
|
||||
|
// 验证 user2 有个人资料
|
||||
|
found2, err := FindProfileByUserId(ctx, db, users[1].Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "avatar2.jpg", found2.Avatar) |
||||
|
|
||||
|
// 验证 user3 没有个人资料
|
||||
|
found3, err := FindProfileByUserId(ctx, db, users[2].Id) |
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, found3) |
||||
|
} |
||||
|
|
||||
|
// TestProfile_UniqueUserId 测试用户ID唯一性约束
|
||||
|
func TestProfile_UniqueUserId(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建用户
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建第一个个人资料
|
||||
|
profile1 := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "avatar1.jpg", |
||||
|
Bio: "Bio 1", |
||||
|
} |
||||
|
|
||||
|
id, err := InsertProfile(ctx, db, profile1) |
||||
|
require.NoError(t, err) |
||||
|
assert.Greater(t, id, int64(0)) |
||||
|
|
||||
|
// 尝试为同一用户创建第二个个人资料(应该失败)
|
||||
|
profile2 := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "avatar2.jpg", |
||||
|
Bio: "Bio 2", |
||||
|
} |
||||
|
|
||||
|
_, err = InsertProfile(ctx, db, profile2) |
||||
|
|
||||
|
// 验证结果 - 应该返回错误(违反唯一性约束)
|
||||
|
require.Error(t, err) |
||||
|
} |
||||
|
|
||||
|
// TestProfile_EmptyFields 测试空字段
|
||||
|
func TestProfile_EmptyFields(t *testing.T) { |
||||
|
db := setupProfileModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建用户
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建空个人资料
|
||||
|
profile := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "", |
||||
|
Bio: "", |
||||
|
} |
||||
|
|
||||
|
id, err := InsertProfile(ctx, db, profile) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Greater(t, id, int64(0)) |
||||
|
|
||||
|
// 验证保存成功
|
||||
|
saved, err := FindOneProfile(ctx, db, id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "", saved.Avatar) |
||||
|
assert.Equal(t, "", saved.Bio) |
||||
|
} |
||||
|
|
||||
|
// BenchmarkInsertProfile 性能测试
|
||||
|
func BenchmarkInsertProfile(b *testing.B) { |
||||
|
db := setupProfileModelTestDB(&testing.T{}) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
profile := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "Test bio", |
||||
|
} |
||||
|
_, _ = InsertProfile(ctx, db, profile) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// BenchmarkFindProfileByUserId 性能测试
|
||||
|
func BenchmarkFindProfileByUserId(b *testing.B) { |
||||
|
db := setupProfileModelTestDB(&testing.T{}) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建测试用户和个人资料
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
profile := &Profile{ |
||||
|
UserId: user.Id, |
||||
|
Avatar: "http://example.com/avatar.jpg", |
||||
|
Bio: "Test bio", |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err = db.Create(profile).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
_, _ = FindProfileByUserId(ctx, db, user.Id) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,368 @@ |
|||||
|
package model |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
"gorm.io/driver/mysql" |
||||
|
"gorm.io/gorm" |
||||
|
) |
||||
|
|
||||
|
// setupUserModelTestDB 创建测试数据库(使用MySQL)
|
||||
|
func setupUserModelTestDB(t *testing.T) *gorm.DB { |
||||
|
t.Helper() |
||||
|
|
||||
|
// 使用 MySQL 进行测试
|
||||
|
dsn := "root:dev123456@tcp(219.159.132.177:17173)/base?charset=utf8mb4&parseTime=true&loc=Local" |
||||
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
err = db.AutoMigrate(&User{}, &Profile{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 清理所有测试数据(TRUNCATE)
|
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 0") |
||||
|
db.Exec("TRUNCATE TABLE profile") |
||||
|
db.Exec("TRUNCATE TABLE user") |
||||
|
db.Exec("SET FOREIGN_KEY_CHECKS = 1") |
||||
|
|
||||
|
return db |
||||
|
} |
||||
|
|
||||
|
// createTestUser 创建测试用户
|
||||
|
func createTestUserModel(t *testing.T, db *gorm.DB) *User { |
||||
|
t.Helper() |
||||
|
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
return user |
||||
|
} |
||||
|
|
||||
|
// TestInsertUser 测试插入用户
|
||||
|
func TestInsertUser(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
user := &User{ |
||||
|
Username: "newuser", |
||||
|
Email: "new@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13900139000", |
||||
|
Status: 1, |
||||
|
} |
||||
|
|
||||
|
id, err := Insert(ctx, db, user) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Greater(t, id, int64(0)) |
||||
|
assert.Equal(t, id, user.Id) |
||||
|
|
||||
|
// 验证数据已保存
|
||||
|
saved, err := FindOne(ctx, db, id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "newuser", saved.Username) |
||||
|
assert.Equal(t, "new@example.com", saved.Email) |
||||
|
} |
||||
|
|
||||
|
// TestFindOneUser 测试根据ID查询用户
|
||||
|
func TestFindOneUser(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUserModel(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 查询用户
|
||||
|
found, err := FindOne(ctx, db, user.Id) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, found) |
||||
|
assert.Equal(t, user.Id, found.Id) |
||||
|
assert.Equal(t, "testuser", found.Username) |
||||
|
assert.Equal(t, "test@example.com", found.Email) |
||||
|
} |
||||
|
|
||||
|
// TestFindOneUser_NotFound 测试查询不存在的用户
|
||||
|
func TestFindOneUser_NotFound(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
found, err := FindOne(ctx, db, 99999) |
||||
|
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, found) |
||||
|
assert.Equal(t, ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestFindOneByEmail 测试根据邮箱查询用户
|
||||
|
func TestFindOneByEmail(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUserModel(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 根据邮箱查询
|
||||
|
found, err := FindOneByEmail(ctx, db, "test@example.com") |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, found) |
||||
|
assert.Equal(t, user.Id, found.Id) |
||||
|
assert.Equal(t, "testuser", found.Username) |
||||
|
} |
||||
|
|
||||
|
// TestFindOneByEmail_NotFound 测试查询不存在的邮箱
|
||||
|
func TestFindOneByEmail_NotFound(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
ctx := context.Background() |
||||
|
|
||||
|
found, err := FindOneByEmail(ctx, db, "nonexistent@example.com") |
||||
|
|
||||
|
require.Error(t, err) |
||||
|
require.Nil(t, found) |
||||
|
assert.Equal(t, ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateUser 测试更新用户
|
||||
|
func TestUpdateUser(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUserModel(t, db) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 修改用户数据
|
||||
|
user.Username = "updateduser" |
||||
|
user.Phone = "13900139000" |
||||
|
|
||||
|
// 更新
|
||||
|
err := Update(ctx, db, user) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 验证更新结果
|
||||
|
updated, err := FindOne(ctx, db, user.Id) |
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, "updateduser", updated.Username) |
||||
|
assert.Equal(t, "13900139000", updated.Phone) |
||||
|
} |
||||
|
|
||||
|
// TestDeleteUser 测试删除用户
|
||||
|
func TestDeleteUser(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
user := createTestUserModel(t, db) |
||||
|
userId := user.Id |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 删除用户
|
||||
|
err := Delete(ctx, db, userId) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 验证用户已被删除
|
||||
|
_, err = FindOne(ctx, db, userId) |
||||
|
require.Error(t, err) |
||||
|
assert.Equal(t, ErrNotFound, err) |
||||
|
} |
||||
|
|
||||
|
// TestFindList 测试查询用户列表
|
||||
|
func TestFindList(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建多个测试用户
|
||||
|
now := time.Now() |
||||
|
users := []User{ |
||||
|
{Username: "user1", Email: "user1@example.com", Password: "pass", Phone: "13800000001", Status: 1, CreatedAt: now, UpdatedAt: now}, |
||||
|
{Username: "user2", Email: "user2@example.com", Password: "pass", Phone: "13800000002", Status: 1, CreatedAt: now, UpdatedAt: now}, |
||||
|
{Username: "user3", Email: "user3@example.com", Password: "pass", Phone: "13800000003", Status: 2, CreatedAt: now, UpdatedAt: now}, |
||||
|
{Username: "user4", Email: "user4@example.com", Password: "pass", Phone: "13800000004", Status: 2, CreatedAt: now, UpdatedAt: now}, |
||||
|
{Username: "user5", Email: "user5@example.com", Password: "pass", Phone: "13800000005", Status: 1, CreatedAt: now, UpdatedAt: now}, |
||||
|
} |
||||
|
|
||||
|
for _, u := range users { |
||||
|
err := db.Create(&u).Error |
||||
|
require.NoError(t, err) |
||||
|
} |
||||
|
|
||||
|
// 测试分页查询
|
||||
|
list, total, err := FindList(ctx, db, 1, 2, "", 0) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(5), total) |
||||
|
assert.Len(t, list, 2) |
||||
|
|
||||
|
// 测试状态筛选
|
||||
|
list, total, err = FindList(ctx, db, 1, 10, "", 1) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(3), total) |
||||
|
|
||||
|
// 测试关键词搜索
|
||||
|
list, total, err = FindList(ctx, db, 1, 10, "user1", 0) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(1), total) |
||||
|
assert.Equal(t, "user1", list[0].Username) |
||||
|
|
||||
|
// 测试第二页
|
||||
|
list, total, err = FindList(ctx, db, 2, 2, "", 0) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(5), total) |
||||
|
assert.Len(t, list, 2) |
||||
|
assert.Equal(t, "user3", list[0].Username) |
||||
|
} |
||||
|
|
||||
|
// TestFindList_EmptyResult 测试查询空列表
|
||||
|
func TestFindList_EmptyResult(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
list, total, err := FindList(ctx, db, 1, 10, "", 0) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(0), total) |
||||
|
assert.Empty(t, list) |
||||
|
} |
||||
|
|
||||
|
// TestFindList_WithPhoneSearch 测试通过手机号搜索
|
||||
|
func TestFindList_WithPhoneSearch(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user1 := &User{Username: "user1", Email: "user1@example.com", Password: "pass", Phone: "13812345678", Status: 1, CreatedAt: now, UpdatedAt: now} |
||||
|
user2 := &User{Username: "user2", Email: "user2@example.com", Password: "pass", Phone: "13887654321", Status: 1, CreatedAt: now, UpdatedAt: now} |
||||
|
|
||||
|
err := db.Create(user1).Error |
||||
|
require.NoError(t, err) |
||||
|
err = db.Create(user2).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 搜索手机号
|
||||
|
list, total, err := FindList(ctx, db, 1, 10, "138123", 0) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(1), total) |
||||
|
assert.Equal(t, "user1", list[0].Username) |
||||
|
} |
||||
|
|
||||
|
// TestFindList_WithEmailSearch 测试通过邮箱搜索
|
||||
|
func TestFindList_WithEmailSearch(t *testing.T) { |
||||
|
db := setupUserModelTestDB(t) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user1 := &User{Username: "user1", Email: "test@company.com", Password: "pass", Phone: "13800000001", Status: 1, CreatedAt: now, UpdatedAt: now} |
||||
|
user2 := &User{Username: "user2", Email: "other@company.com", Password: "pass", Phone: "13800000002", Status: 1, CreatedAt: now, UpdatedAt: now} |
||||
|
|
||||
|
err := db.Create(user1).Error |
||||
|
require.NoError(t, err) |
||||
|
err = db.Create(user2).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 搜索邮箱
|
||||
|
_, total, err := FindList(ctx, db, 1, 10, "@company.com", 0) |
||||
|
|
||||
|
require.NoError(t, err) |
||||
|
assert.Equal(t, int64(2), total) |
||||
|
} |
||||
|
|
||||
|
// BenchmarkInsertUser 性能测试
|
||||
|
func BenchmarkInsertUser(b *testing.B) { |
||||
|
db := setupUserModelTestDB(&testing.T{}) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: time.Now(), |
||||
|
UpdatedAt: time.Now(), |
||||
|
} |
||||
|
_, _ = Insert(ctx, db, user) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// BenchmarkFindOneUser 性能测试
|
||||
|
func BenchmarkFindOneUser(b *testing.B) { |
||||
|
db := setupUserModelTestDB(&testing.T{}) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建测试用户
|
||||
|
now := time.Now() |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
_, _ = FindOne(ctx, db, user.Id) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// BenchmarkFindList 性能测试
|
||||
|
func BenchmarkFindList(b *testing.B) { |
||||
|
db := setupUserModelTestDB(&testing.T{}) |
||||
|
ctx := context.Background() |
||||
|
|
||||
|
// 创建100个测试用户
|
||||
|
now := time.Now() |
||||
|
for i := 0; i < 100; i++ { |
||||
|
user := &User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "encryptedpassword", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
err := db.Create(user).Error |
||||
|
if err != nil { |
||||
|
b.Fatal(err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
b.ResetTimer() |
||||
|
for i := 0; i < b.N; i++ { |
||||
|
_, _, _ = FindList(ctx, db, 1, 10, "", 0) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,166 @@ |
|||||
|
package profile |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"testing" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/youruser/base/internal/svc" |
||||
|
"github.com/youruser/base/internal/types" |
||||
|
"github.com/youruser/base/model" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
// Ensure imports are used |
||||
|
var _ = svc.ServiceContext{} |
||||
|
var _ = types.GetProfileResponse{} |
||||
|
|
||||
|
// setupTestDB 创建测试数据库并返回 ServiceContext(使用MySQL) |
||||
|
func setupTestDB(t *testing.T) (*svc.ServiceContext, func()) { |
||||
|
t.Helper() |
||||
|
|
||||
|
// 使用 MySQL 进行测试 |
||||
|
dsn := "root:root@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=true&loc=Local" |
||||
|
db, err := gorm.Open(dsn, &gorm.Config{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 自动迁移表 |
||||
|
err = db.AutoMigrate(&model.User{}, &model.Profile{}) |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
// 创建测试 ServiceContext |
||||
|
svcCtx := &svc.ServiceContext{ |
||||
|
DB: db, |
||||
|
} |
||||
|
|
||||
|
// 清理函数 |
||||
|
cleanup := func() { |
||||
|
sqlDB, _ := db.DB() |
||||
|
if sqlDB != nil { |
||||
|
sqlDB.Close() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return svcCtx, cleanup |
||||
|
} |
||||
|
|
||||
|
// createTestUser 创建测试用户 |
||||
|
func createTestUser(t *testing.T, db *gorm.DB) *model.User { |
||||
|
t.Helper() |
||||
|
|
||||
|
now := time.Now() |
||||
|
user := &model.User{ |
||||
|
Username: "testuser", |
||||
|
Email: "test@example.com", |
||||
|
Password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8", |
||||
|
Phone: "13800138000", |
||||
|
Status: 1, |
||||
|
CreatedAt: now, |
||||
|
UpdatedAt: now, |
||||
|
} |
||||
|
|
||||
|
err := db.Create(user).Error |
||||
|
require.NoError(t, err) |
||||
|
|
||||
|
return user |
||||
|
} |
||||
|
|
||||
|
// TestGetProfile_Success 测试成功获取个人信息 |
||||
|
func TestGetProfile_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户 |
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
createTestProfile(t, svcCtx.DB, user.Id) |
||||
|
|
||||
|
// 设置上下文,包含用户ID |
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例 |
||||
|
logic := NewGetProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 执行测试 |
||||
|
resp, err := logic.GetProfile() |
||||
|
|
||||
|
// 验证结果 |
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "testuser", resp.Username) |
||||
|
assert.Equal(t, "test@example.com", resp.Email) |
||||
|
assert.Equal(t, "13800138000", resp.Phone) |
||||
|
assert.Equal(t, "http://example.com/avatar.jpg", resp.Avatar) |
||||
|
assert.Equal(t, "This is a test bio", resp.Bio) |
||||
|
assert.Equal(t, 1, resp.Status) |
||||
|
} |
||||
|
|
||||
|
// TestUpdateProfile_Success 测试成功更新个人资料 |
||||
|
func TestUpdateProfile_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户 |
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID |
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例 |
||||
|
logic := NewUpdateProfileLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备更新请求数据 |
||||
|
req := &types.UpdateProfileRequest{ |
||||
|
Username: "updateduser", |
||||
|
Phone: "13900139000", |
||||
|
Avatar: "http://example.com/newavatar.jpg", |
||||
|
Bio: "Updated bio text", |
||||
|
} |
||||
|
|
||||
|
// 执行测试 |
||||
|
resp, err := logic.UpdateProfile(req) |
||||
|
|
||||
|
// 验证结果 |
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
|
||||
|
assert.Equal(t, user.Id, resp.Id) |
||||
|
assert.Equal(t, "updateduser", resp.Username) |
||||
|
assert.Equal(t, "13900139000", resp.Phone) |
||||
|
assert.Equal(t, "http://example.com/newavatar.jpg", resp.Avatar) |
||||
|
assert.Equal(t, "Updated bio text", resp.Bio) |
||||
|
} |
||||
|
|
||||
|
// TestChangePassword_Success 测试成功修改密码 |
||||
|
func TestChangePassword_Success(t *testing.T) { |
||||
|
svcCtx, cleanup := setupTestDB(t) |
||||
|
defer cleanup() |
||||
|
|
||||
|
// 创建测试用户,密码为 "password" |
||||
|
user := createTestUser(t, svcCtx.DB) |
||||
|
|
||||
|
// 设置上下文,包含用户ID |
||||
|
ctx := context.WithValue(context.Background(), "userId", user.Id) |
||||
|
|
||||
|
// 创建 Logic 实例 |
||||
|
logic := NewChangePasswordLogic(ctx, svcCtx) |
||||
|
|
||||
|
// 准备修改密码请求数据 |
||||
|
req := &types.ChangePasswordRequest{ |
||||
|
OldPassword: "password", |
||||
|
NewPassword: "newpassword123", |
||||
|
} |
||||
|
|
||||
|
// 执行测试 |
||||
|
resp, err := logic.ChangePassword(req) |
||||
|
|
||||
|
// 验证结果 |
||||
|
require.NoError(t, err) |
||||
|
require.NotNil(t, resp) |
||||
|
assert.Equal(t, 200, resp.Code) |
||||
|
assert.Equal(t, "修改密码成功", resp.Message) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set CGO_ENABLED=1 |
||||
|
go test -v ./internal/logic/... %* |
||||
|
pause |
||||
Loading…
Reference in new issue