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) } }