feat: 系统性改进后端测试体系
- 新增 6 个测试场景 (config load pipe, handler errors, service aggregation, engine degradation, openai decoder edges, negative tests) - 更新测试工具规格 (mockgen, in-memory SQLite) - 覆盖率目标从 >80% 提升至 >85% - 新增 test-unit 和 test-integration Makefile 命令 - 新增死代码清理和 mockgen 需求 - 归档变更至 openspec/changes/archive/2026-04-22-improve-backend-testing/
This commit is contained in:
@@ -7,49 +7,40 @@ import (
|
||||
|
||||
"nex/backend/internal/config"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// SetupTestDB initializes an in-memory SQLite database with auto-migration.
|
||||
// Uses :memory: mode with MaxOpenConns(1) to ensure all operations share the
|
||||
// same connection, avoiding "database is closed" errors from connection pool.
|
||||
// Enables foreign key constraints for SQLite.
|
||||
func SetupTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
|
||||
db, err := gorm.Open(sqlite.Open(":memory:?_foreign_keys=on"), &gorm.Config{})
|
||||
assert.NoError(t, err, "failed to open test database")
|
||||
require.NoError(t, err, "failed to open test database")
|
||||
|
||||
// 限制为单连接,确保 :memory: 数据库不被连接池丢弃
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err, "failed to get underlying sql.DB")
|
||||
require.NoError(t, err, "failed to get underlying sql.DB")
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
sqlDB.SetConnMaxLifetime(0)
|
||||
|
||||
err = db.AutoMigrate(&config.Provider{}, &config.Model{}, &config.UsageStats{})
|
||||
assert.NoError(t, err, "failed to auto-migrate test database")
|
||||
require.NoError(t, err, "failed to auto-migrate test database")
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
// CleanupTestDB closes the database after a brief delay to allow async
|
||||
// goroutines (e.g. stats recording) to finish.
|
||||
func CleanupTestDB(t *testing.T, db *gorm.DB) {
|
||||
t.Helper()
|
||||
|
||||
// 等待异步 goroutine(如 statsService.Record)完成
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
assert.NoError(t, err, "failed to get underlying sql.DB")
|
||||
require.NoError(t, err, "failed to get underlying sql.DB")
|
||||
|
||||
err = sqlDB.Close()
|
||||
assert.NoError(t, err, "failed to close test database")
|
||||
require.NoError(t, err, "failed to close test database")
|
||||
}
|
||||
|
||||
// CreateTestProvider creates a test provider and returns it.
|
||||
func CreateTestProvider(t *testing.T, db *gorm.DB, id string) config.Provider {
|
||||
t.Helper()
|
||||
|
||||
@@ -62,13 +53,11 @@ func CreateTestProvider(t *testing.T, db *gorm.DB, id string) config.Provider {
|
||||
}
|
||||
|
||||
err := db.Create(&provider).Error
|
||||
assert.NoError(t, err, "failed to create test provider")
|
||||
require.NoError(t, err, "failed to create test provider")
|
||||
|
||||
return provider
|
||||
}
|
||||
|
||||
// CreateTestModel creates a test model and returns it.
|
||||
// Does NOT assert on error - returns the model and error for caller to verify.
|
||||
func CreateTestModel(t *testing.T, db *gorm.DB, id string, providerID string, modelName string) (config.Model, error) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user