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

Vapor单元测试后数据库未清空,二次运行报冲突错误如何解决?

问题根因

  1. 迁移回滚逻辑失效
    所有Migration的revert方法调用的是.update()方法,该方法仅用于修改表结构,不会删除已有表或清空表数据,autoRevert()执行时完全无法清理上一次测试写入的用户数据,第二次测试重复注册同个邮箱时就会返回HTTPStatus.conflict。同时无修改逻辑的空update请求发送到Postgres后,会触发syntax error at end of input语法报错。
  2. 测试环境数据库端口不匹配
    docker-compose-testing.yml中测试服务配置的DATABASE_PORT=5434,但postgres服务默认端口为5432,未做端口修改配置,会导致测试服务数据库连接异常。

修复方案

1. 修正所有迁移的回滚逻辑

将所有Migration的revert方法中的.update()替换为.delete(),执行回滚时直接删除整个表,保证每次测试重建的表都是空表:

修正后的用户迁移回滚代码

struct UserModelMigration_v1_0_0: Migration {
  func prepare(on database: Database) -> EventLoopFuture<Void> {
    database.schema(UserModel.schema)
      .id()
      .field(UserModel.Key.email, .string, .required)
      .field(UserModel.Key.password, .string, .required)
      .unique(on: UserModel.Key.email)
      .create()
  }

  func revert(on database: Database) -> EventLoopFuture<Void> {
    database
      .schema(UserModel.schema)
      .delete()
  }
}

修正后的地址迁移回滚代码

struct AddressModelMigration_v1_0_0: Migration {
  func prepare(on database: Database) -> EventLoopFuture<Void> {
    database.schema(AddressModel.schema)
      .id()
      .field(AddressModel.Key.streetLineOne, .string, .required)
      .field(AddressModel.Key.city, .string, .required)
      .field(AddressModel.Key.userID, .uuid, .required,
             .references(UserModel.schema, .id,
                         onDelete: .cascade,
                         onUpdate: .cascade))
      .unique(on: AddressModel.Key.userID)
      .create()
  }

  func revert(on database: Database) -> EventLoopFuture<Void> {
    database
      .schema(AddressModel.schema)
      .delete()
  }
}

迁移回滚会按照添加顺序逆序执行,先删除Address表再删除User表,符合外键约束要求,不会触发依赖报错。

2. 修正测试环境端口配置

修改docker-compose-testing.yml中测试服务的数据库端口配置,和postgres默认端口对齐:

testingonlinux:
  environment:
    - DATABASE_HOST=postgres
    - DATABASE_PORT=5432

3. 可选:测试执行时自动清理Docker残留

运行测试时添加--volumes参数,测试结束后自动删除postgres的挂载卷,确保每次测试都是完全干净的数据库环境:

docker-compose -f docker-compose-testing.yml down --volumes && docker-compose -f docker-compose-testing.yml up --abort-on-container-exit

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:15:00