starter-kit/current/unit-testing.md
ulflow_phattt2901 9a8c40eee2
All checks were successful
CI Pipeline / Lint (push) Successful in 3m49s
CI Pipeline / Security Scan (push) Successful in 5m16s
CI Pipeline / Test (push) Successful in 2m21s
CI Pipeline / Build (push) Successful in 1m17s
CI Pipeline / Notification (push) Successful in 2s
fix: implement resource access middleware and router setup with auth integration
2025-06-05 13:30:08 +07:00

5.4 KiB

Tài liệu Unit Testing

Mục lục

  1. Giới thiệu
  2. Cấu trúc thư mục test
  3. Các loại test case
  4. Cách chạy test
  5. Best Practices

Giới thiệu

Tài liệu này mô tả các test case đã được triển khai trong dự án, giúp đảm bảo chất lượng và độ tin cậy của mã nguồn.

Cấu trúc thư mục test

internal/
  transport/
    http/
      middleware/
        auth_test.go        # Test xác thực và phân quyền
        middleware_test.go   # Test CORS và rate limiting
      handler/
        health_handler_test.go  # Test health check endpoints
  service/
    auth_service_test.go      # Test service xác thực

Các loại test case

Auth Middleware

Xác thực người dùng

  1. TestNewAuthMiddleware

    • Mục đích: Kiểm tra khởi tạo AuthMiddleware
    • Input: AuthService
    • Expected: Trả về instance AuthMiddleware
  2. TestAuthenticate_Success

    • Mục đích: Xác thực thành công với token hợp lệ
    • Input: Header Authorization với token hợp lệ
    • Expected: Trả về status 200 và lưu thông tin user vào context
  3. TestAuthenticate_NoAuthHeader

    • Mục đích: Không có header Authorization
    • Input: Request không có header Authorization
    • Expected: Trả về lỗi 401 Unauthorized
  4. TestAuthenticate_InvalidTokenFormat

    • Mục đích: Kiểm tra định dạng token không hợp lệ
    • Input:
      • Token không có "Bearer" prefix
      • Token rỗng sau "Bearer"
    • Expected: Trả về lỗi 401 Unauthorized
  5. TestAuthenticate_InvalidToken

    • Mục đích: Token không hợp lệ hoặc hết hạn
    • Input: Token không hợp lệ
    • Expected: Trả về lỗi 401 Unauthorized

Phân quyền (RBAC)

  1. TestRequireRole_Success

    • Mục đích: Người dùng có role yêu cầu
    • Input: User có role phù hợp
    • Expected: Cho phép truy cập
  2. TestRequireRole_Unauthenticated

    • Mục đích: Chưa xác thực
    • Input: Không có thông tin xác thực
    • Expected: Trả về lỗi 401 Unauthorized
  3. TestRequireRole_Forbidden

    • Mục đích: Không có quyền truy cập
    • Input: User không có role yêu cầu
    • Expected: Trả về lỗi 403 Forbidden

Helper Functions

  1. TestGetUserFromContext

    • Mục đích: Lấy thông tin user từ context
    • Input: Context có chứa user
    • Expected: Trả về thông tin user
  2. TestGetUserFromContext_NotFound

    • Mục đích: Không tìm thấy user trong context
    • Input: Context không có user
    • Expected: Trả về lỗi
  3. TestGetUserIDFromContext

    • Mục đích: Lấy user ID từ context
    • Input: Context có chứa user
    • Expected: Trả về user ID
  4. TestGetUserIDFromContext_InvalidType

    • Mục đích: Kiểm tra lỗi khi kiểu dữ liệu không hợp lệ
    • Input: Context có giá trị không phải kiểu *Claims
    • Expected: Trả về lỗi

CORS Middleware

  1. TestDefaultCORSConfig

    • Mục đích: Kiểm tra cấu hình CORS mặc định
    • Expected: Cấu hình mặc định cho phép tất cả origins
  2. TestCORS

    • Mục đích: Kiểm tra hành vi CORS
    • Các trường hợp:
      • Cho phép tất cả origins
      • Chỉ cho phép origin cụ thể
      • Xử lý preflight request

Rate Limiting

  1. TestDefaultRateLimiterConfig

    • Mục đích: Kiểm tra cấu hình rate limiter mặc định
    • Expected: Giới hạn mặc định được áp dụng
  2. TestRateLimit

    • Mục đích: Kiểm tra hoạt động của rate limiter
    • Expected: Chặn request khi vượt quá giới hạn

Security Config

  1. TestSecurityConfig
    • Mục đích: Kiểm tra cấu hình bảo mật
    • Các trường hợp:
      • Cấu hình mặc định
      • Áp dụng cấu hình cho router

Cách chạy test

Chạy tất cả test

go test ./...

Chạy test với coverage

go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

Chạy test cụ thể

go test -run ^TestName$

Best Practices

  1. Đặt tên test rõ ràng

    • Sử dụng cấu trúc: Test[FunctionName]_[Scenario]
    • Ví dụ: TestAuthenticate_InvalidToken
  2. Mỗi test một trường hợp

    • Mỗi test function chỉ kiểm tra một trường hợp cụ thể
    • Sử dụng subtests cho các test case liên quan
  3. Kiểm tra cả trường hợp lỗi

    • Kiểm tra cả các trường hợp thành công và thất bại
    • Đảm bảo có thông báo lỗi rõ ràng
  4. Sử dụng mock cho các phụ thuộc

    • Sử dụng thư viện testify/mock để tạo mock
    • Đảm bảo test độc lập với các thành phần bên ngoài
  5. Kiểm tra biên

    • Kiểm tra các giá trị biên và trường hợp đặc biệt
    • Ví dụ: empty string, nil, giá trị âm, v.v.
  6. Giữ test đơn giản

    • Test cần dễ hiểu và dễ bảo trì
    • Tránh logic phức tạp trong test
  7. Đảm bảo test chạy nhanh

    • Tránh I/O không cần thiết
    • Sử dụng t.Parallel() cho các test độc lập