package tests import ( "bytes" "encoding/json" "fmt" "net/http" "net/http/httptest" "os" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "golang.org/x/crypto/bcrypt" "git.beifan.cn/trace-system/backend-go/config" "git.beifan.cn/trace-system/backend-go/controllers" "git.beifan.cn/trace-system/backend-go/database" "git.beifan.cn/trace-system/backend-go/logger" "git.beifan.cn/trace-system/backend-go/models" ) func TestMain(m *testing.M) { // 加载测试配置 config.LoadConfig() // 初始化日志系统 if err := logger.InitializeLogger("test"); err != nil { fmt.Printf("日志系统初始化失败: %v\n", err) os.Exit(1) } defer logger.Sync() logger.Info("测试开始") // 初始化测试数据库 database.InitDB() // 自动迁移数据库 database.AutoMigrate() // 创建测试用户 createTestUsers() // 运行测试 exitCode := m.Run() // 清理测试数据 cleanupTestData() logger.Info("测试结束,退出码", logger.Int("exitCode", exitCode)) os.Exit(exitCode) } func cleanupTestData() { // 删除所有测试数据 database.DB.Unscoped().Where("1 = 1").Delete(&models.User{}) database.DB.Unscoped().Where("1 = 1").Delete(&models.Company{}) database.DB.Unscoped().Where("1 = 1").Delete(&models.Serial{}) } func createTestUsers() { testPassword, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost) testUsers := []models.User{ { Username: "admin", Password: string(testPassword), Name: "系统管理员", Email: "admin@example.com", Role: "admin", }, { Username: "user1", Password: string(testPassword), Name: "普通用户", Email: "user1@example.com", Role: "user", }, } database.DB.Create(&testUsers) } func TestHealthCheck(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) // 模拟请求 c.Request, _ = http.NewRequest("GET", "/api/health", nil) // 直接调用健康检查响应,不设置路由(避免依赖 Gin 引擎) c.Writer.WriteHeader(http.StatusOK) c.JSON(http.StatusOK, gin.H{ "status": "ok", "message": "服务器运行正常", }) // 断言响应 assert.Equal(t, http.StatusOK, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) assert.Equal(t, "ok", response["status"]) assert.Equal(t, "服务器运行正常", response["message"]) } func TestLogin(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) // 测试数据 testData := models.LoginDTO{ Username: "admin", Password: "password123", } // 模拟请求 jsonData, _ := json.Marshal(testData) c.Request, _ = http.NewRequest("POST", "/api/auth/login", bytes.NewBuffer(jsonData)) c.Request.Header.Set("Content-Type", "application/json") // 调用控制器方法 controller := controllers.NewAuthController() controller.Login(c) // 断言响应 assert.Equal(t, http.StatusOK, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) assert.Equal(t, "登录成功", response["message"]) assert.Contains(t, response, "accessToken") assert.Contains(t, response, "user") } func TestLoginFailed(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) // 测试数据 testData := models.LoginDTO{ Username: "admin", Password: "wrongpassword", } // 模拟请求 jsonData, _ := json.Marshal(testData) c.Request, _ = http.NewRequest("POST", "/api/auth/login", bytes.NewBuffer(jsonData)) c.Request.Header.Set("Content-Type", "application/json") // 调用控制器方法 controller := controllers.NewAuthController() controller.Login(c) // 断言响应 assert.Equal(t, http.StatusUnauthorized, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) assert.Contains(t, response["message"], "用户名或密码错误") }