package jwtx import ( "fmt" "testing" "time" "github.com/golang-jwt/jwt/v4" ) func TestGenerateJwtToken(t *testing.T) { tests := []struct { name string userId int64 secret string expireTime int64 wantErr bool }{ { name: "正常生成token", userId: 7816, secret: "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA", expireTime: 2592000, wantErr: false, }, { name: "用户ID为0", userId: 0, secret: "test-secret-key", expireTime: 3600, wantErr: false, }, { name: "用户ID为负数", userId: -1, secret: "test-secret-key", expireTime: 3600, wantErr: false, }, { name: "过期时间为0", userId: 12345, secret: "test-secret-key", expireTime: 0, wantErr: false, }, { name: "过期时间为负数", userId: 12345, secret: "test-secret-key", expireTime: -3600, wantErr: false, }, { name: "空密钥", userId: 12345, secret: "", expireTime: 3600, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { token, err := GenerateJwtToken(tt.userId, tt.secret, tt.expireTime) fmt.Printf("name: %s, token: %s\n", tt.name, token) if tt.wantErr { if err == nil { t.Errorf("GenerateJwtToken() 期望错误,但没有返回错误") } return } if err != nil { t.Errorf("GenerateJwtToken() 错误 = %v, 期望无错误", err) return } if token == "" { t.Errorf("GenerateJwtToken() 返回空token") return } // 验证生成的token是否可以正确解析 parsedUserId, err := ParseJwtToken(token, tt.secret) if err != nil { t.Errorf("ParseJwtToken() 解析生成的token失败: %v", err) return } if parsedUserId != tt.userId { t.Errorf("ParseJwtToken() 解析出的userId = %v, 期望 %v", parsedUserId, tt.userId) } }) } } func TestGenerateJwtToken_ExpirationTime(t *testing.T) { userId := int64(12345) secret := "test-secret-key" expireTime := int64(3600) // 1小时 token, err := GenerateJwtToken(userId, secret, expireTime) if err != nil { t.Fatalf("GenerateJwtToken() 错误 = %v", err) } // 解析token并验证过期时间 parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) { return []byte(secret), nil }) if err != nil { t.Fatalf("jwt.Parse() 错误 = %v", err) } claims, ok := parsedToken.Claims.(jwt.MapClaims) if !ok { t.Fatal("无法获取JWT claims") } // 验证签发时间 iat, ok := claims["iat"].(float64) if !ok { t.Fatal("无法获取签发时间") } // 验证过期时间 exp, ok := claims["exp"].(float64) if !ok { t.Fatal("无法获取过期时间") } // 验证过期时间是否正确设置 expectedExp := float64(time.Now().Unix()) + float64(expireTime) if exp < expectedExp-5 || exp > expectedExp+5 { // 允许5秒的误差 t.Errorf("过期时间不正确: 期望接近 %v, 实际 %v", expectedExp, exp) } // 验证签发时间 expectedIat := float64(time.Now().Unix()) if iat < expectedIat-5 || iat > expectedIat+5 { // 允许5秒的误差 t.Errorf("签发时间不正确: 期望接近 %v, 实际 %v", expectedIat, iat) } } func TestGenerateJwtToken_Concurrent(t *testing.T) { userId := int64(12345) secret := "test-secret-key" expireTime := int64(3600) // 并发测试 ch := make(chan string, 10) errCh := make(chan error, 10) for i := 0; i < 10; i++ { go func() { token, err := GenerateJwtToken(userId, secret, expireTime) if err != nil { errCh <- err return } ch <- token }() } // 收集结果 tokens := make([]string, 0, 10) for i := 0; i < 10; i++ { select { case token := <-ch: tokens = append(tokens, token) case err := <-errCh: t.Errorf("并发生成token时发生错误: %v", err) } } // 验证所有token都是有效的 for i, token := range tokens { parsedUserId, err := ParseJwtToken(token, secret) if err != nil { t.Errorf("token[%d] 解析失败: %v", i, err) continue } if parsedUserId != userId { t.Errorf("token[%d] 解析出的userId = %v, 期望 %v", i, parsedUserId, userId) } } }