Skip to content

Commit 48a61d4

Browse files
author
Andrea Scuderi
committed
Improve Unit Tests by fixing warnings
1 parent 8cdc391 commit 48a61d4

File tree

5 files changed

+194
-29
lines changed

5 files changed

+194
-29
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2024 (c) Andrea Scuderi - https://github.com/swift-serverless
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import BreezeDynamoDBService
16+
@testable import BreezeLambdaAPI
17+
import SotoDynamoDB
18+
19+
actor BreezeDynamoDBManagerMock: BreezeDynamoDBManaging {
20+
let keyName: String
21+
22+
enum BreezeDynamoDBManagerError: Error {
23+
case invalidRequest
24+
case invalidItem
25+
}
26+
27+
28+
private var response: (any BreezeCodable)?
29+
private var keyedResponse: (any BreezeCodable)?
30+
31+
func setupMockResponse(response: (any BreezeCodable)?, keyedResponse: (any BreezeCodable)?) {
32+
self.keyedResponse = keyedResponse
33+
self.response = response
34+
}
35+
36+
init(db: SotoDynamoDB.DynamoDB, tableName: String, keyName: String) {
37+
self.keyName = keyName
38+
}
39+
40+
func createItem<T: BreezeCodable>(item: T) async throws -> T {
41+
guard let response = self.response as? T else {
42+
throw BreezeDynamoDBManagerError.invalidRequest
43+
}
44+
return response
45+
}
46+
47+
func readItem<T: BreezeCodable>(key: String) async throws -> T {
48+
guard let response = self.keyedResponse as? T,
49+
response.key == key
50+
else {
51+
throw BreezeDynamoDBManagerError.invalidRequest
52+
}
53+
return response
54+
}
55+
56+
func updateItem<T: BreezeCodable>(item: T) async throws -> T {
57+
guard let response = self.keyedResponse as? T,
58+
response.key == item.key
59+
else {
60+
throw BreezeDynamoDBManagerError.invalidRequest
61+
}
62+
return response
63+
}
64+
65+
func deleteItem<T: BreezeCodable>(item: T) async throws {
66+
guard let response = self.keyedResponse,
67+
response.key == item.key,
68+
response.createdAt == item.createdAt,
69+
response.updatedAt == item.updatedAt
70+
else {
71+
throw BreezeDynamoDBManagerError.invalidRequest
72+
}
73+
return
74+
}
75+
76+
var limit: Int?
77+
var exclusiveKey: String?
78+
func listItems<T: BreezeCodable>(key: String?, limit: Int?) async throws -> ListResponse<T> {
79+
guard let response = self.response as? T else {
80+
throw BreezeDynamoDBManagerError.invalidItem
81+
}
82+
self.limit = limit
83+
self.exclusiveKey = key
84+
return ListResponse(items: [response], lastEvaluatedKey: key)
85+
}
86+
}

Tests/BreezeDynamoDBServiceTests/BreezeDynamoDBManagerTests.swift

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ struct BreezeDynamoDBManagerTests {
7373
try #require(value.updatedAt?.iso8601 != nil)
7474
do {
7575
_ = try await sut.createItem(item: product2023)
76-
Issue.record("It should throw conditionalCheckFailedException")
76+
Issue.record("It should throw DynamoDBErrorType.conditionalCheckFailedException")
7777
} catch {
78-
try #require(error != nil)
78+
let dynamoDBError = try #require(error as? DynamoDBErrorType)
79+
#expect(dynamoDBError == .conditionalCheckFailedException)
7980
}
8081
try await removeTable(tableName: uuid)
8182
}
@@ -102,9 +103,10 @@ struct BreezeDynamoDBManagerTests {
102103
#expect(value.key == "2023")
103104
do {
104105
let _: Product = try await sut.readItem(key: "2022")
105-
Issue.record("It should throw when Item is missing")
106+
Issue.record("It should throw ServiceError.notfound when Item is missing")
106107
} catch {
107-
try #require(error != nil)
108+
let dynamoDBError = try #require(error as? BreezeDynamoDBManager.ServiceError)
109+
#expect(dynamoDBError == .notFound)
108110
}
109111
try await removeTable(tableName: uuid)
110112
}
@@ -140,16 +142,18 @@ struct BreezeDynamoDBManagerTests {
140142
#expect(value.updatedAt?.iso8601 != newValue.updatedAt?.iso8601)
141143
do {
142144
let _: Product = try await sut.updateItem(item: product2023)
143-
Issue.record("It should throw conditionalCheckFailedException")
145+
Issue.record("It should throw AWSResponseError ValidationException")
144146
} catch {
145-
try #require(error != nil)
147+
let dynamoDBError = try #require(error as? AWSResponseError)
148+
#expect(dynamoDBError.errorCode == "ValidationException")
146149
}
147150

148151
do {
149152
let _: Product = try await sut.updateItem(item: product2022)
150-
Issue.record("It should throw conditionalCheckFailedException")
153+
Issue.record("It should throw AWSResponseError ValidationException")
151154
} catch {
152-
try #require(error != nil)
155+
let dynamoDBError = try #require(error as? AWSResponseError)
156+
#expect(dynamoDBError.errorCode == "ValidationException")
153157
}
154158
try await removeTable(tableName: uuid)
155159
}
@@ -171,9 +175,10 @@ struct BreezeDynamoDBManagerTests {
171175
let sut = try await givenTable(tableName: uuid)
172176
do {
173177
try await sut.deleteItem(item: product2022)
174-
Issue.record("It should throw ServiceError.missingParameters")
178+
Issue.record("It should throw DynamoDBErrorType.conditionalCheckFailedException")
175179
} catch {
176-
try #require(error != nil)
180+
let dynamoDBError = try #require(error as? DynamoDBErrorType)
181+
#expect(dynamoDBError == .conditionalCheckFailedException)
177182
}
178183
try await removeTable(tableName: uuid)
179184
}
@@ -189,7 +194,8 @@ struct BreezeDynamoDBManagerTests {
189194
try await sut.deleteItem(item: value)
190195
Issue.record("It should throw ServiceError.missingParameters")
191196
} catch {
192-
try #require(error != nil)
197+
let dynamoDBError = try #require(error as? BreezeDynamoDBManager.ServiceError)
198+
#expect(dynamoDBError == .missingParameters)
193199
}
194200
try await removeTable(tableName: uuid)
195201
}
@@ -205,7 +211,8 @@ struct BreezeDynamoDBManagerTests {
205211
try await sut.deleteItem(item: value)
206212
Issue.record("It should throw ServiceError.missingParameters")
207213
} catch {
208-
try #require(error != nil)
214+
let dynamoDBError = try #require(error as? BreezeDynamoDBManager.ServiceError)
215+
#expect(dynamoDBError == .missingParameters)
209216
}
210217
try await removeTable(tableName: uuid)
211218
}
@@ -219,9 +226,10 @@ struct BreezeDynamoDBManagerTests {
219226
value.updatedAt = Date().iso8601
220227
do {
221228
try await sut.deleteItem(item: value)
222-
Issue.record("It should throw ServiceError.missingParameters")
229+
Issue.record("It should throw DynamoDBErrorType.conditionalCheckFailedException")
223230
} catch {
224-
try #require(error != nil)
231+
let dynamoDBError = try #require(error as? DynamoDBErrorType)
232+
#expect(dynamoDBError == .conditionalCheckFailedException)
225233
}
226234
try await removeTable(tableName: uuid)
227235
}
@@ -235,9 +243,10 @@ struct BreezeDynamoDBManagerTests {
235243
value.createdAt = Date().iso8601
236244
do {
237245
try await sut.deleteItem(item: value)
238-
Issue.record("It should throw ServiceError.missingParameters")
246+
Issue.record("It should throw DynamoDBErrorType.conditionalCheckFailedException")
239247
} catch {
240-
try #require(error != nil)
248+
let dynamoDBError = try #require(error as? DynamoDBErrorType)
249+
#expect(dynamoDBError == .conditionalCheckFailedException)
241250
}
242251
try await removeTable(tableName: uuid)
243252
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2024 (c) Andrea Scuderi - https://github.com/swift-serverless
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import SotoDynamoDB
16+
import AsyncHTTPClient
17+
import Logging
18+
import Testing
19+
@testable import BreezeDynamoDBService
20+
21+
@Suite
22+
struct BreezeDynamoDBServiceTests {
23+
@Test
24+
func testInitPrepareBreezeDynamoDBManager() async throws {
25+
let sut = await makeBreezeDynamoDBConfig()
26+
let manager = await sut.dbManager()
27+
#expect(manager is BreezeDynamoDBManager, "Expected BreezeDynamoDBManager instance")
28+
try await sut.gracefulShutdown()
29+
}
30+
31+
@Test
32+
func testGracefulShutdownCanBeCalledMultipleTimes() async throws {
33+
let sut = await makeBreezeDynamoDBConfig()
34+
try await sut.gracefulShutdown()
35+
try await sut.gracefulShutdown()
36+
}
37+
38+
@Test
39+
func testMockInjection() async throws {
40+
let config = BreezeDynamoDBConfig(
41+
region: .useast1,
42+
tableName: "TestTable",
43+
keyName: "TestKey",
44+
)
45+
let logger = Logger(label: "BreezeDynamoDBServiceTests")
46+
let httpConfig = BreezeHTTPClientConfig(timeout: .seconds(10), logger: logger)
47+
let sut = await BreezeDynamoDBService(
48+
config: config,
49+
httpConfig: httpConfig,
50+
logger: logger,
51+
DBManagingType: BreezeDynamoDBManagerMock.self
52+
)
53+
let manager = await sut.dbManager()
54+
#expect(manager is BreezeDynamoDBManagerMock, "Expected BreezeDynamoDBManager instance")
55+
try await sut.gracefulShutdown()
56+
}
57+
58+
private func makeBreezeDynamoDBConfig() async -> BreezeDynamoDBService {
59+
let config = BreezeDynamoDBConfig(
60+
region: .useast1,
61+
tableName: "TestTable",
62+
keyName: "TestKey",
63+
)
64+
let logger = Logger(label: "BreezeDynamoDBServiceTests")
65+
let httpConfig = BreezeHTTPClientConfig(timeout: .seconds(10), logger: logger)
66+
return await BreezeDynamoDBService(
67+
config: config,
68+
httpConfig: httpConfig,
69+
logger: logger,
70+
)
71+
}
72+
}

Tests/BreezeLambdaAPITests/BreezeDynamoDBManagerMock.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,26 @@ import SotoDynamoDB
1818

1919
actor BreezeDynamoDBManagerMock: BreezeDynamoDBManaging {
2020
let keyName: String
21-
21+
2222
private var response: (any BreezeCodable)?
2323
private var keyedResponse: (any BreezeCodable)?
2424

2525
func setupMockResponse(response: (any BreezeCodable)?, keyedResponse: (any BreezeCodable)?) {
26-
self.keyedResponse = keyedResponse
27-
self.response = response
26+
self.keyedResponse = keyedResponse
27+
self.response = response
2828
}
29-
29+
3030
init(db: SotoDynamoDB.DynamoDB, tableName: String, keyName: String) {
3131
self.keyName = keyName
3232
}
33-
33+
3434
func createItem<T: BreezeCodable>(item: T) async throws -> T {
3535
guard let response = self.response as? T else {
3636
throw BreezeLambdaAPIError.invalidRequest
3737
}
3838
return response
3939
}
40-
40+
4141
func readItem<T: BreezeCodable>(key: String) async throws -> T {
4242
guard let response = self.keyedResponse as? T,
4343
response.key == key
@@ -46,7 +46,7 @@ actor BreezeDynamoDBManagerMock: BreezeDynamoDBManaging {
4646
}
4747
return response
4848
}
49-
49+
5050
func updateItem<T: BreezeCodable>(item: T) async throws -> T {
5151
guard let response = self.keyedResponse as? T,
5252
response.key == item.key
@@ -55,7 +55,7 @@ actor BreezeDynamoDBManagerMock: BreezeDynamoDBManaging {
5555
}
5656
return response
5757
}
58-
58+
5959
func deleteItem<T: BreezeCodable>(item: T) async throws {
6060
guard let response = self.keyedResponse,
6161
response.key == item.key,
@@ -66,7 +66,7 @@ actor BreezeDynamoDBManagerMock: BreezeDynamoDBManaging {
6666
}
6767
return
6868
}
69-
69+
7070
var limit: Int?
7171
var exclusiveKey: String?
7272
func listItems<T: BreezeCodable>(key: String?, limit: Int?) async throws -> ListResponse<T> {

Tests/BreezeLambdaAPITests/BreezeLambdaHandlerTests.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,9 @@ struct BreezeLambdaHandlerTests {
222222
keyedResponse: keyedResponse,
223223
with: request
224224
)
225-
let response: BreezeEmptyResponse = try apiResponse.decodeBody()
225+
let _: BreezeEmptyResponse = try apiResponse.decodeBody()
226226
#expect(apiResponse.statusCode == .ok)
227227
#expect(apiResponse.headers == [ "Content-Type": "application/json" ])
228-
#expect(response != nil)
229228
}
230229

231230
@Test
@@ -241,10 +240,9 @@ struct BreezeLambdaHandlerTests {
241240
keyedResponse: keyedResponse,
242241
with: request
243242
)
244-
let response: BreezeEmptyResponse = try apiResponse.decodeBody()
243+
let _: BreezeEmptyResponse = try apiResponse.decodeBody()
245244
#expect(apiResponse.statusCode == .notFound)
246245
#expect(apiResponse.headers == [ "Content-Type": "application/json" ])
247-
#expect(response != nil)
248246
}
249247

250248
@Test

0 commit comments

Comments
 (0)