我正在嘗試在沒有創建用戶并且可以第一次注冊時運行測驗。測驗第一次完美運行并通過。問題是,如果我第二次運行它,我的容器不會被正確洗掉,我們最終會得到一個HTTPStatus.conflict而不是.ok,所以用戶確實已經存在。
我正在我的 MacBook 上運行一個 Docker 容器docker-compose-testing,docker-compose并testing.Dockerfile設定。
運行測驗時也會觸發此錯誤:
caught error: "server: syntax error at end of input (scanner_yyerror)"
這里缺少什么?會不會autoRevert()和autoMigrate()清除我的資料庫?
func testSignUpRoute_userDoesNotExistInDatabase_userSignUpAndHTTPStatusIsOk() throws {
// Configuration in setUp and tearDown.
var app = Application(.testing)
defer { app.shutdown() }
try configure(app)
try app.autoRevert().wait()
try app.autoMigrate().wait()
// Given
let expected: HTTPStatus = .ok
let headers = [
"email": "[email protected]",
"password": "fooEncrypted"
]
// When
try app.test(.POST, "users/signup") { request in
try request.content.encode(headers)
} afterResponse: { response in
let result = response.status
// Then
XCTAssertEqual(result, expected, "Response status must be \(expected)")
}
}
這是我的遷移在configure.swift檔案中發生的順序:
public func configure(_ app: Application) throws {
app.migrations.add(UserModelMigration_v1_0_0())
app.migrations.add(AddressModelMigration_v1_0_0())
}
這就是我恢復所有模型的方式。AddressModel和CompanyModel是@OptionalChild的UserModel。問題似乎來自here,但我無法指出。
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)
.update()
}
}
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)
.update()
}
}
這是我的docker-compose-testing.yml檔案
version: '3'
services:
testingonlinux:
depends_on:
- postgres
build:
context: .
dockerfile: testing.Dockerfile
environment:
- DATABASE_HOST=postgres
- DATABASE_PORT=5434
postgres:
image: "postgres"
environment:
- POSTGRES_DB=foo_db_testing
- POSTGRES_USER=foo_user
- POSTGRES_PASSWORD=foo_password
這是我的docker-compose.yml檔案
version: '3.8'
volumes:
db_data:
x-shared_environment: &shared_environment
LOG_LEVEL: ${LOG_LEVEL:-debug}
DATABASE_HOST: db
DATABASE_NAME: vapor_database
DATABASE_USERNAME: vapor_username
DATABASE_PASSWORD: vapor_password
services:
app:
image: FooServerSide:latest
build:
context: .
environment:
<<: *shared_environment
depends_on:
- db
ports:
- '8080:8080'
# user: '0' # uncomment to run as root for testing purposes even though Dockerfile defines 'vapor' user.
command: ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]
migrate:
image: FooServerSide:latest
build:
context: .
environment:
<<: *shared_environment
depends_on:
- db
command: ["migrate", "--yes"]
deploy:
replicas: 0
revert:
image: FooServerSide:latest
build:
context: .
environment:
<<: *shared_environment
depends_on:
- db
command: ["migrate", "--revert", "--yes"]
deploy:
replicas: 0
db:
image: postgres:12-alpine
volumes:
- db_data:/var/lib/postgresql/data/pgdata
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: vapor_username
POSTGRES_PASSWORD: vapor_password
POSTGRES_DB: vapor_database
ports:
- '5432:5432'
還有我的 testing.Dockerfile
FROM swift:5.5
WORKDIR /package
COPY . ./
CMD ["swift", "test", "--enable-test-discovery"]
uj5u.com熱心網友回復:
對我來說突出的問題是您的恢復方法似乎實際上并沒有洗掉資料庫中的資料或洗掉表。
我有使用 Vapor 中的恢復功能的類似測驗,遷移如下所示:
public struct ListV1: Migration {
public func prepare(on database: Database) -> EventLoopFuture<Void> {
return database.schema("Lists")
.id()
.field("listId", .int, .required, .custom("UNIQUE"))
.field("listString", .string, .required)
.field("createdAt", .datetime)
.field("updatedAt", .datetime)
.create()
}
public func revert(on database: Database) -> EventLoopFuture<Void> {
return database.schema("Lists").delete()
}
}
更改您的還原功能以使用.delete()(如下所示)可能會解決您的問題:
struct AddressModelMigration_v1_0_0: Migration {
...
func revert(on database: Database) -> EventLoopFuture<Void> {
database
.schema(AddressModel.schema)
.delete()
}
}
uj5u.com熱心網友回復:
你為什么不把你的 App 類放在代表sut(被測系統)的測驗變數中并覆寫你的測驗setup()和tearDown()方法?
如:
final class AppTests: XCTestCase {
var sut: Application!
override setup() {
super.setup()
sut = Application(.testing)
}
override tearDown() {
sut.shutdown()
sut = nil
super.tearDown()
}
// MARK: - Given
// MARK: - When
func whenMigrationsAreSet() async throws {
sut.migrations.add(UserModelMigration_v1_0_0())
sut.migrations.add(AddressModelMigration_v1_0_0())
sut.migrations.add(CompanyModelMigration_v1_0_0())
try await app.autoRevert()
try await app.autoMigrate()
}
// MARK: - Tests
func testSignUpRoute_whenUserDoesNotExist_thenUserSignUpAndHTTPStatusIsOk() async throws {
try await whenMigrationsAreSet()
let headers = [
"email": "[email protected]",
"password": "fooEncrypted",
]
let requestExpectation = expectation("request completed")
let responseExpectation = expectation("got response")
var result: HTTPStatus?
try sut.test(.POST, "users/signup") { request in
try request.content.encode(headers)
requestExpectation.fullfill()
} afterResponse { response in
result = response.status
responseExpectation.fullfill()
}
wait(for: [requestExpectation, responseExpectation], timeout: 0.5, enforceOrder: true)
XCTAssertEqual(result, .ok)
}
}
無論如何,我還對您的測驗增加了期望,因為它似乎正在以舊方式完成一些異步作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/362645.html
