单元测试
概述
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 框架中服务方法的正确性。