Skip to content

单元测试

概述

Fun 框架提供了内置的测试工具,可以方便地对服务进行单元测试。通过模拟客户端请求和验证返回结果,开发者可以确保服务方法按预期工作。

测试结构

测试函数定义

测试函数需要遵循 Go 语言的测试规范,以 Test 开头并接收 *testing.T 参数:

go
func TestGetPuzzleCode(t *testing.T) {
    // 测试逻辑
}

构造测试请求

GetRequestInfo 函数

使用 fun.GetRequestInfo 函数创建测试请求:

go
request := fun.GetRequestInfo(
    t,                   // testing.T 实例
    service.SystemService{}, // 服务实例
    "GetPuzzleCode",     // 方法名
    nil,                 // DTO 数据(方法参数)
    map[string]string{}  // 状态信息
)

参数说明:

  • [t]: testing.T实例
  • [service]: 服务实例
  • [methodName]: 要测试的方法名
  • [dto]: DTO 数据(方法参数),可以是 nil 或具体的数据结构
  • state: 状态信息(如认证令牌等)

执行测试请求

MockRequest 函数

使用 fun.MockRequest 函数执行模拟请求:

go
result := fun.MockRequest[*ReturnType](t, request)

参数说明:

  • 泛型参数:期望的返回值类型
  • [t]: 实例
  • request: 请求信息

完整测试示例

无参数方法测试

go
func TestGetPuzzleCode(t *testing.T) {
    request := fun.GetRequestInfo(
        t, 
        service.SystemService{}, 
        "GetPuzzleCode", 
        nil, 
        map[string]string{}
    )

    result := fun.MockRequest[[]string](t, request)
    
    // 验证结果
    fmt.Println(result)
}

带参数方法测试

go
func TestCheckToken(t *testing.T) {
    // 准备 DTO 数据
    dto := systemDto.CheckToken{
        Token: "1", 
        Code:  "1",
    }
    
    request := fun.GetRequestInfo(
        t, 
        service.SystemService{}, 
        "CheckToken", 
        dto, 
        map[string]string{}
    )

    result := fun.MockRequest[*string](t, request)
    
    // 验证结果
    fun.DebugLogger(result)
}

带状态信息的测试

go
func TestProtectedMethod(t *testing.T) {
    dto := userDto.LoginDto{
        Username: "testuser",
        Password: "testpass",
    }
    
    request := fun.GetRequestInfo(
        t,
        service.UserService{},
        "Login",
        dto,
        map[string]string{
            "ip": "127.0.0.1",
        }
    )
    
    result := fun.MockRequest[*AuthToken](t, request)
    
    // 验证结果
    if result.Status != fun.SuccessStatus {
        t.Errorf("Expected success, got status %d", result.Status)
    }
    
    if result.Data == nil {
        t.Error("Expected auth token, got nil")
    }
}

结果验证

状态码验证

go
// 验证成功状态
if result.Status != fun.SuccessStatus {
    t.Errorf("Expected success status, got %d", result.Status)
}

// 验证错误状态
if result.Status != fun.ErrorStatus {
    t.Errorf("Expected error status, got %d", result.Status)
}

数据验证

go
// 验证返回数据不为空
if result.Data == nil {
    t.Error("Expected data, got nil")
}

// 验证具体字段值
if result.Data.Username != "expected_username" {
    t.Errorf("Expected username 'expected_username', got '%s'", result.Data.Username)
}

最佳实践

1. 测试命名规范

go
// 好的命名
func TestUserService_CreateUser(t *testing.T) { }
func TestUserService_GetUser_NotFound(t *testing.T) { }
func TestUserService_UpdateUser_InvalidData(t *testing.T) { }

// 不推荐的命名
func Test1(t *testing.T) { }
func TestCreate(t *testing.T) { }

2. 测试数据准备

go
func TestUserService_CreateUser(t *testing.T) {
    // 准备测试数据
    dto := userDto.CreateUserDto{
        Name:  "Test User",
        Email: "test@example.com",
    }
    
    request := fun.GetRequestInfo(t, service.UserService{}, "CreateUser", dto, nil)
    
    result := fun.MockRequest[*User](t, request)
    
    // 验证结果
    if result.Data == nil {
        t.Fatal("Expected user data")
    }
    
    if result.Data.Name != "Test User" {
        t.Errorf("Expected name 'Test User', got '%s'", result.Data.Name)
    }
}

3. 错误情况测试

go
func TestUserService_CreateUser_InvalidEmail(t *testing.T) {
    dto := userDto.CreateUserDto{
        Name:  "Test User",
        Email: "invalid-email", // 无效邮箱
    }
    
    request := fun.GetRequestInfo(t, service.UserService{}, "CreateUser", dto, nil)
    
    result := fun.MockRequest[*User](t, request)
    
    // 验证返回错误
    if result.Status != fun.ErrorStatus {
        t.Errorf("Expected error status, got %d", result.Status)
    }
    
    if result.Code == nil || *result.Code != 400 {
        t.Errorf("Expected error code 400, got %v", result.Code)
    }
}

通过以上方式,您可以编写有效的单元测试来验证 Fun 框架中服务方法的正确性。