You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试后如何重置Docker中配置的Redis数据库以清除残留令牌?

解决测试间Redis令牌残留导致的测试失败问题

问题背景

测试时将用户访问令牌存储在Docker容器的Redis中,首次测试正常,但因无法重置容器,令牌会在测试间残留,导致用户会话持续存在,引发后续测试失败。该令牌配合AsyncBearerAuthenticator使用,用于校验请求头中的令牌是否能通过指定路由的身份验证。

已实现辅助方法在测试时存入令牌,但需要在每次测试后删除令牌或重置数据库。

现有代码

测试辅助方法

extension Application {

  @discardableResult
  func test(
    _ method: HTTPMethod,
    _ path: String,
    user: UserModel? = .none,
    tokenProtected: Bool = true,
    content: (any Content)? = .none,
    afterResponse: (XCTHTTPResponse) throws -> () = { _ in },
    file: StaticString = #file,
    line: UInt = #line
  ) async throws -> XCTApplicationTester {

    var headers: HTTPHeaders = [:]
    if let user, tokenProtected {
      let accessToken = try AccessTokenModel.generate(for: user)
      try await self.redis.set(RedisKey(accessToken.value), toJSON: accessToken)
      headers.add(name: "Authorization", value: "Bearer \(accessToken.value)")
    }

    return try test(
      method,
      path,
      headers: headers,
      file: file,
      line: line,
      beforeRequest: { if let content { try $0.content.encode(content) }},
      afterResponse: afterResponse
    )
  }
}

Redis配置(configure.swift)

app.redis.configuration = try RedisConfiguration(hostname: "localhost", port: 6380)
app.sessions.use(.redis)

Redis Docker启动命令

docker run --name myapp_redis_testing -p 6380:6379 -d redis

解决方案

方案1:每次测试后删除当前令牌

修改测试辅助方法,在afterResponse回调中添加令牌删除逻辑,确保测试完成后清理当前生成的令牌:

extension Application {

  @discardableResult
  func test(
    _ method: HTTPMethod,
    _ path: String,
    user: UserModel? = .none,
    tokenProtected: Bool = true,
    content: (any Content)? = .none,
    afterResponse: (XCTHTTPResponse) throws -> () = { _ in },
    file: StaticString = #file,
    line: UInt = #line
  ) async throws -> XCTApplicationTester {

    var headers: HTTPHeaders = [:]
    var generatedAccessToken: AccessTokenModel? = nil
    
    if let user, tokenProtected {
      let accessToken = try AccessTokenModel.generate(for: user)
      try await self.redis.set(RedisKey(accessToken.value), toJSON: accessToken)
      headers.add(name: "Authorization", value: "Bearer \(accessToken.value)")
      generatedAccessToken = accessToken
    }

    return try test(
      method,
      path,
      headers: headers,
      file: file,
      line: line,
      beforeRequest: { if let content { try $0.content.encode(content) }},
      afterResponse: { response in
        try afterResponse(response)
        // 清理当前测试生成的令牌
        if let token = generatedAccessToken {
          try await self.redis.delete(RedisKey(token.value))
        }
      }
    )
  }
}

方案2:测试前后重置Redis数据库

如果需要彻底清空Redis(比如测试间有其他会话数据残留),可以在测试套件的setUp或tearDown方法中执行Redis的FLUSHDB命令:

final class MyAppTests: XCTestCase {
  var app: Application!

  override func setUp() async throws {
    try await super.setUp()
    app = Application(.testing)
    try configure(app)
    // 测试前清空Redis数据库
    try await app.redis.send(.flushDB)
  }

  override func tearDown() async throws {
    // 测试后清空Redis数据库(可选,根据需求选择在setUp或tearDown执行)
    try await app.redis.send(.flushDB)
    app.shutdown()
    try await super.tearDown()
  }

  // 测试用例...
}

方案3:为测试使用独立的Redis数据库

Redis默认有16个数据库,可以为测试指定单独的数据库,避免与其他环境冲突,同时清空时不影响其他数据:

  1. 修改configure.swift中的Redis配置,指定数据库编号:
app.redis.configuration = try RedisConfiguration(hostname: "localhost", port: 6380, database: 1) // 使用数据库1
app.sessions.use(.redis)
  1. 在测试的setUp或tearDown中清空该数据库:
try await app.redis.send(.flushDB)

方案4:Docker容器级别重置

如果需要彻底重置容器,可以在测试脚本中添加Docker命令,每次测试前重启并清空容器:

# 停止并删除现有容器
docker stop myapp_redis_testing && docker rm myapp_redis_testing
# 重新创建容器
docker run --name myapp_redis_testing -p 6380:6379 -d redis

可以将上述命令集成到测试的前置脚本中,比如在Xcode的Scheme预动作中添加,或者使用Makefile管理测试流程。

总结

  • 若只需清理当前测试生成的令牌,方案1最轻量化;
  • 若测试间有其他Redis数据残留,方案2或3更彻底;
  • 若需要完全隔离测试环境,方案4适合集成到自动化测试流程中。

内容的提问来源于stack exchange,提问作者Roland Lariotte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:07:10