Files
junhong_cmp_fiber/tests/integration/health_test.go
huang 984ccccc63 docs(constitution): 新增数据库设计原则(v2.4.0)
在项目宪章中新增第九条原则"数据库设计原则",明确禁止使用数据库外键约束和ORM关联标签。

主要变更:
- 新增原则IX:数据库设计原则(Database Design Principles)
- 强制要求:数据库表不得使用外键约束
- 强制要求:GORM模型不得使用ORM关联标签(foreignKey、hasMany等)
- 强制要求:表关系必须通过ID字段手动维护
- 强制要求:关联数据查询必须显式编写,避免ORM魔法
- 强制要求:时间字段由GORM处理,不使用数据库触发器

设计理念:
- 提升业务逻辑灵活性(无数据库约束限制)
- 优化高并发性能(无外键检查开销)
- 增强代码可读性(显式查询,无隐式预加载)
- 简化数据库架构和迁移流程
- 支持分布式和微服务场景

版本升级:2.3.0 → 2.4.0(MINOR)
2025-11-13 13:40:19 +08:00

170 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package integration
import (
"context"
"net/http/httptest"
"testing"
"github.com/break/junhong_cmp_fiber/internal/handler"
"github.com/gofiber/fiber/v2"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// TestHealthCheckNormal 测试健康检查 - 正常状态
func TestHealthCheckNormal(t *testing.T) {
// 初始化日志
logger, _ := zap.NewDevelopment()
// 初始化内存数据库
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
// 初始化 Redis 客户端(使用本地 Redis
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DB: 0,
})
defer rdb.Close()
// 创建 Fiber 应用
app := fiber.New()
// 创建健康检查处理器
healthHandler := handler.NewHealthHandler(db, rdb, logger)
app.Get("/health", healthHandler.Check)
// 发送测试请求
req := httptest.NewRequest("GET", "/health", nil)
resp, err := app.Test(req)
require.NoError(t, err)
defer resp.Body.Close()
// 验证响应状态码
assert.Equal(t, 200, resp.StatusCode)
// 验证响应内容
// 注意:这里可以进一步解析 JSON 响应体验证详细信息
}
// TestHealthCheckDatabaseDown 测试健康检查 - 数据库异常
func TestHealthCheckDatabaseDown(t *testing.T) {
t.Skip("需要模拟数据库连接失败的场景")
// 初始化日志
logger, _ := zap.NewDevelopment()
// 初始化一个会失败的数据库连接
db, err := gorm.Open(sqlite.Open("/invalid/path/test.db"), &gorm.Config{})
if err != nil {
// 预期会失败
t.Log("数据库连接失败(预期行为)")
}
// 初始化 Redis 客户端
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DB: 0,
})
defer rdb.Close()
// 创建 Fiber 应用
app := fiber.New()
// 创建健康检查处理器
healthHandler := handler.NewHealthHandler(db, rdb, logger)
app.Get("/health", healthHandler.Check)
// 发送测试请求
req := httptest.NewRequest("GET", "/health", nil)
resp, err := app.Test(req)
require.NoError(t, err)
defer resp.Body.Close()
// 验证响应状态码应该是 503 (Service Unavailable)
assert.Equal(t, 503, resp.StatusCode)
}
// TestHealthCheckRedisDown 测试健康检查 - Redis 异常
func TestHealthCheckRedisDown(t *testing.T) {
// 初始化日志
logger, _ := zap.NewDevelopment()
// 初始化内存数据库
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
// 初始化一个连接到无效地址的 Redis 客户端
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:9999", // 无效端口
DB: 0,
})
defer rdb.Close()
// 创建 Fiber 应用
app := fiber.New()
// 创建健康检查处理器
healthHandler := handler.NewHealthHandler(db, rdb, logger)
app.Get("/health", healthHandler.Check)
// 发送测试请求
req := httptest.NewRequest("GET", "/health", nil)
resp, err := app.Test(req)
require.NoError(t, err)
defer resp.Body.Close()
// 验证响应状态码应该是 503 (Service Unavailable)
assert.Equal(t, 503, resp.StatusCode)
}
// TestHealthCheckDetailed 测试健康检查 - 验证详细信息
func TestHealthCheckDetailed(t *testing.T) {
// 初始化日志
logger, _ := zap.NewDevelopment()
// 初始化内存数据库
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
// 初始化 Redis 客户端
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DB: 0,
})
defer rdb.Close()
// 测试 Redis 连接
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
t.Skip("Redis 未运行,跳过测试")
}
// 创建 Fiber 应用
app := fiber.New()
// 创建健康检查处理器
healthHandler := handler.NewHealthHandler(db, rdb, logger)
app.Get("/health", healthHandler.Check)
// 发送测试请求
req := httptest.NewRequest("GET", "/health", nil)
resp, err := app.Test(req)
require.NoError(t, err)
defer resp.Body.Close()
// 验证响应状态码
assert.Equal(t, 200, resp.StatusCode)
// TODO: 解析 JSON 响应并验证包含以下字段:
// - status: "healthy"
// - postgres: "up"
// - redis: "up"
// - timestamp
}