为什么在实施单元测试时我的 postgres 表不存在?

问题描述

我开始在 Vapor 4 项目中实施单元测试,但每次测试后都没有删除/创建 users postgres 表。它仅适用于 1 个测试,然后将它们全部崩溃。

即使我没有执行任何测试,编译器也会因为这个错误而停止:

caught error: "prevIoUsError(server: table "users" does not exist (DropErrorMsgNonExistent))"

我的数据库在 Docker 容器中与 Postgresql 一起运行。当我手动删除此容器并再次运行测试时,没有错误。当我第二次运行它时,错误又回来了。

为什么每次测试后都没有删除我的表?

这是我的测试文件,我已经实现了一个简单的测试来尝试管道:

import XCTVapor
@testable import App

class BaseXCTestCase: XCTestCase {

  var app: Application!

  override func setUpWithError() throws {
    try super.setUpWithError()
    app = Application(.testing)
    try configure(app).  // The error is caught here.
  }

  override func tearDownWithError() throws {
    app.shutdown()
    try super.tearDownWithError()
  }

  // This test crashes if everything goes well,but it
  // doesn't even run as the crashes appears in configure.swift.
  func test_zero() {
    XCTFail("Tests not yet implemented")
  }
}

这是我的 users 表:

import Fluent

struct usermodelMigration_v1_0_0: Migration {

  func prepare(on database: Database) -> EventLoopFuture<Void> {
    
    database.schema("users")
      .id()
      .field("email",.string,.required)
      .field("password",.required)
      .field("appleID",.string)
      .unique(on: "email")
      .create()
  }

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

这是我为测试设置迁移的 configure.swift 文件的一部分:

import Fluent
import FluentPostgresDriver
import Vapor

public func configure(_ app: Application) throws {
  // MARK: Database
  let databaseName: String
  let databasePort: Int

  if app.environment == .testing {
    databaseName = "db_testing"
    databasePort = 5434
  }
  else {
    databaseName = "db_development"
    databasePort = 5433
  }

  app.databases.use(.postgres(
    hostname: "localhost",port: databasePort,username: "username",password: "password",database: databaseName
  ),as: .psql)

  // MARK: Migrations
  app.migrations.add(usermodelMigration_v1_0_0())

  // MARK: Clear Database
  if app.environment == .testing {
    try app.autoRevert().wait()
  }

  if !app.environment.isRelease {
    try app.autoMigrate().wait()
  }
}

还有两个文件,我在其中添加代码以在 Docker 容器中运行测试。

文件docker-compose-testing.yml

version: '3'
services:
  serverside-app:
    depends_on:
      - postgres
    build:
      context: .
      dockerfile: testing.Dockerfile
    environment:
      - DATABASE_HOST=postgres
      - DATABASE_PORT=5434
  postgres:
    image: "postgres"
    environment:
      - POSTGRES_DB=db_testing
      - POSTGRES_USER=username
      - POSTGRES_PASSWORD=password

文件testing.Dockerfile

FROM swift:5.3
workdir /package
copY . ./
CMD ["swift","test","--enable-test-discovery"]

解决方法

如果表不存在,您的还原将失败。 将其更改为 try? app.autoRevert().wait() 并且您自动迁移到 try? app.autoMigrate().wait() 将忽略任何错误。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...