单元测试 #

一、测试概述 #

1.1 Go测试框架 #

Go内置testing包,提供轻量级的测试框架。

1.2 测试文件命名 #

text
main.go      → main_test.go
user.go      → user_test.go
handler.go   → handler_test.go

二、基本测试 #

2.1 测试函数 #

go
package main

import (
    "testing"
)

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5
    
    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}

2.2 运行测试 #

bash
# 运行所有测试
go test ./...

# 运行特定包
go test ./handlers

# 运行特定测试
go test -run TestAdd

# 显示详细输出
go test -v

# 查看覆盖率
go test -cover

三、Fiber应用测试 #

3.1 测试HTTP处理 #

go
package main

import (
    "io"
    "net/http/httptest"
    "testing"
    
    "github.com/gofiber/fiber/v2"
    "github.com/stretchr/testify/assert"
)

func TestHelloHandler(t *testing.T) {
    app := fiber.New()
    
    app.Get("/hello", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })
    
    req := httptest.NewRequest("GET", "/hello", nil)
    resp, err := app.Test(req, -1)
    
    assert.NoError(t, err)
    assert.Equal(t, 200, resp.StatusCode)
    
    body, _ := io.ReadAll(resp.Body)
    assert.Equal(t, "Hello, World!", string(body))
}

3.2 测试JSON响应 #

go
func TestJSONHandler(t *testing.T) {
    app := fiber.New()
    
    app.Get("/user", func(c *fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "name": "John",
            "age":  30,
        })
    })
    
    req := httptest.NewRequest("GET", "/user", nil)
    req.Header.Set("Accept", "application/json")
    
    resp, err := app.Test(req)
    assert.NoError(t, err)
    assert.Equal(t, 200, resp.StatusCode)
    
    body, _ := io.ReadAll(resp.Body)
    assert.Contains(t, string(body), "John")
}

3.3 测试POST请求 #

go
func TestCreateUser(t *testing.T) {
    app := fiber.New()
    
    app.Post("/users", func(c *fiber.Ctx) error {
        var user struct {
            Name  string `json:"name"`
            Email string `json:"email"`
        }
        
        if err := c.BodyParser(&user); err != nil {
            return c.Status(400).SendString("Invalid JSON")
        }
        
        return c.Status(201).JSON(user)
    })
    
    body := `{"name":"John","email":"john@example.com"}`
    req := httptest.NewRequest("POST", "/users", strings.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    
    resp, err := app.Test(req)
    assert.NoError(t, err)
    assert.Equal(t, 201, resp.StatusCode)
}

四、测试中间件 #

4.1 测试认证中间件 #

go
func TestAuthMiddleware(t *testing.T) {
    app := fiber.New()
    
    app.Use(func(c *fiber.Ctx) error {
        token := c.Get("Authorization")
        if token == "" {
            return c.Status(401).JSON(fiber.Map{"error": "Unauthorized"})
        }
        return c.Next()
    })
    
    app.Get("/protected", func(c *fiber.Ctx) error {
        return c.SendString("Protected")
    })
    
    // 测试无Token
    t.Run("NoToken", func(t *testing.T) {
        req := httptest.NewRequest("GET", "/protected", nil)
        resp, _ := app.Test(req)
        assert.Equal(t, 401, resp.StatusCode)
    })
    
    // 测试有Token
    t.Run("WithToken", func(t *testing.T) {
        req := httptest.NewRequest("GET", "/protected", nil)
        req.Header.Set("Authorization", "Bearer token")
        resp, _ := app.Test(req)
        assert.Equal(t, 200, resp.StatusCode)
    })
}

五、表驱动测试 #

5.1 表驱动测试模式 #

go
func TestValidateEmail(t *testing.T) {
    tests := []struct {
        name     string
        email    string
        expected bool
    }{
        {"Valid email", "test@example.com", true},
        {"Invalid email", "invalid", false},
        {"Empty email", "", false},
        {"No domain", "test@", false},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := ValidateEmail(tt.email)
            assert.Equal(t, tt.expected, result)
        })
    }
}

六、测试覆盖率 #

6.1 生成覆盖率报告 #

bash
# 查看覆盖率
go test -cover

# 生成覆盖率文件
go test -coverprofile=coverage.out

# 查看覆盖率详情
go tool cover -func=coverage.out

# 生成HTML报告
go tool cover -html=coverage.out -o coverage.html

七、总结 #

7.1 测试要点 #

要点 说明
测试文件 *_test.go
测试函数 TestXxx
断言 testify/assert
覆盖率 go test -cover

7.2 下一步 #

现在你已经掌握了单元测试,接下来让我们学习 API测试,了解接口测试方法!

最后更新:2026-03-28