test: 补齐 handler/repository/domain 层单元测试
This commit is contained in:
117
internal/repository/sql_scan_test.go
Normal file
117
internal/repository/sql_scan_test.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// mockQueryer implements sqlQueryer for testing
|
||||
type mockQueryer struct {
|
||||
rows *sql.Rows
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *mockQueryer) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
|
||||
return m.rows, m.err
|
||||
}
|
||||
|
||||
func TestScanSingleRow_QueryError(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mockErr := errors.New("query failed")
|
||||
q := &mockQueryer{err: mockErr}
|
||||
|
||||
var dest int
|
||||
err := scanSingleRow(ctx, q, "SELECT 1", nil, &dest)
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
}
|
||||
if !errors.Is(err, mockErr) {
|
||||
t.Errorf("expected query error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanSingleRow_NoRows(t *testing.T) {
|
||||
// This test requires a real database connection to create sql.Rows.
|
||||
// scanSingleRow is designed to work with any sqlQueryer, but creating
|
||||
// a mock sql.Rows without a real driver is complex.
|
||||
// We test the behavior through integration with the test database.
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
// Use the raw sql.DB from gorm
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatalf("get sql.DB failed: %v", err)
|
||||
}
|
||||
|
||||
var dest int
|
||||
err = scanSingleRow(ctx, sqlDB, "SELECT 1 WHERE 1=0", nil, &dest)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for no rows, got nil")
|
||||
}
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
t.Errorf("expected sql.ErrNoRows, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanSingleRow_Success(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatalf("get sql.DB failed: %v", err)
|
||||
}
|
||||
|
||||
var dest int
|
||||
err = scanSingleRow(ctx, sqlDB, "SELECT 42", nil, &dest)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
if dest != 42 {
|
||||
t.Errorf("expected 42, got %d", dest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanSingleRow_MultipleColumns(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatalf("get sql.DB failed: %v", err)
|
||||
}
|
||||
|
||||
var a, b int
|
||||
err = scanSingleRow(ctx, sqlDB, "SELECT 1, 2", nil, &a, &b)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
if a != 1 {
|
||||
t.Errorf("expected a=1, got %d", a)
|
||||
}
|
||||
if b != 2 {
|
||||
t.Errorf("expected b=2, got %d", b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanSingleRow_StringResult(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatalf("get sql.DB failed: %v", err)
|
||||
}
|
||||
|
||||
var dest string
|
||||
err = scanSingleRow(ctx, sqlDB, "SELECT 'hello'", nil, &dest)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
if dest != "hello" {
|
||||
t.Errorf("expected 'hello', got %q", dest)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user