You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
5.6 KiB
238 lines
5.6 KiB
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)
|
|
}
|
|
}
|
|
|