单元测试 URL Swift 中的参数
Unit Testing URL Parameters in Swift
我正在尝试使用 TDD 将 URL
单元化为 Swift。我想确保 URL
等于预期的 URL
。我正在使用 Router
enum
,使用 Alamofire
来创建我的 URL
。因此,作为 Router
enum
的 属性,我有一个 Dictionary<String,String>?
属性,因为我可能不需要其他 URL
的参数。但是,我确实需要用于身份验证的参数 URL
.
parameters
Dictionary<String,String>?
如下:
internal enum Router: URLConvertible {
internal static let baseURLString = "https://xxx.xxxxxx.xxx"
case authentication(clientID: String)
}
extension Router {
var pathString: String {
switch self {
case .authentication: return "xxxxx/xxxxx/xxxxxxxxx"
}
}
var method: HTTPMethod {
switch self {
case .authentication: return .get
}
}
var parameters: Dictionary<String, String>? {
switch self {
case .authentication(let clientID): return ["xxxxx": "xxxx", "client_id": clientID]
}
}
func asURL() throws -> URL {
switch self {
case .authentication:
return URL(string: "https://xxx.xxxxxx.xxx/xxxxx/xxxxx/xxxxxxxxx?xxxxx=xxxx&client_id=xxxxxxxxxx")!
}
}
}
到目前为止,我已经能够使用 TDD 方式成功编写所有代码。我卡住的地方是测试返回的 URL
。由于 parameters
是 Dictionary<String,String>?
类型,我想使用以下逻辑迭代 parameters
:
var parametersStringArray = Array<Dictionary<String,String>>()
for (key, value) in parameters {
// Create a parameter string from each set
// Something like the following:
let parameterString = String(describing: \(key)=\(value))
parametersStringArray.append(parameterString)
}
let parametersString = parametersStringArray.joined(separator: "&")
let fullURLString = baseURLString + "?\(parametersString)"
return URL(string: fullURLString)!
通过创建这样的参数,当我根据 asURL() throws -> URL
中的 Router
enum
返回的 URL
测试预期的 URL
时,它部分时间可能会失败,因为参数是在没有预期顺序的情况下添加到 URL
字符串中的。换句话说,如果我预期的 URL 是 https://xxx.xxxxxx.xxx?xxxxx=xxxx&client_id=xxxxxxxxxx
,它可以通过以相反的顺序返回参数来匹配或失败,如下所示:https://xxx.xxxxxx.xxx?client_id=xxxxxxxxxx&xxxxx=xxxx
.
对于我测试 URL
是否有更好的解决方案以确保当参数可以按任何顺序返回时返回正确的 URL
因为它们被添加到 URL
's string when iterates them?
我是否应该创建两个带有两种参数的 URL
s 并匹配任何一种?我认为不合适的原因是因为您拥有的参数越多,您必须创建越多的 URL
来进行测试。
我目前用于测试 URL
身份验证的测试如下:
import XCTest
import Alamofire
@testable import Projects
class AuthenticationURLTests: XCTestCase {
func test_API_BaseURLString_IsCorrect() {
let baseURLString = Router.baseURLString
let expectedBaseURLString = "https://xxx.xxxxxx.xxx/"
XCTAssertEqual(baseURLString, expectedBaseURLString, "Base URL does not match expected base URL. Expected base URLs to match.")
}
func test_API_OAuthPath_IsCorrect() {
let pathString = Router.authentication(clientID: "xxxxxxxxxx").pathString
let expectedPathString = "xxxxx/xxxxx/xxxxxxxxx"
XCTAssertEqual(pathString, expectedPathString, "Path string does not match expected path string. Expected path strings to match.")
}
func test_API_OAuthMethod_IsCorrect() {
let method = Router.authentication(clientID: "xxxxxxxxxx").method
let expectedMethod = HTTPMethod.get
XCTAssertEqual(method, expectedMethod, "HTTP methods do not match. Expected HTTP methods to match.")
}
func test_API_OAuth_ParametersContainsKeyForXXXXX() {
let scopeString = Router.authentication(clientID: "xxxxxxxxxx").parameters?["xxxxx"]
let expectedScopeString = "xxxx"
XCTAssertEqual(scopeString, expectedScopeString, "Scope strings do not match. Expected scope strings to match.")
}
func test_API_OAuth_ParametersContainsKeyForClientID() {
let clientID = Router.authentication(clientID: "12345abcde").parameters?["client_id"]
let expectedClientID_Fake = "12345abcde"
XCTAssertEqual(clientID, expectedClientID_Fake, "Client IDs do not match. Expected client IDs to match.")
}
func test_API_OAuth_URLIsCorrect() {
do {
let url = try Router.authentication(clientID: "12345abcde").asURL()
// Here, I want to ensure that the `URL`s match:
let expectedURL = URL(string: https://xxx.xxxxxx.xxx?xxxxx=xxxx&client_id=xxxxxxxxxx)!
} catch { XCTFail("Could not create URL for OAuth") }
}
}
对于所提供代码中的所有 x
,我们深表歉意。我想确保我没有提供任何关于我客户申请的信息。
你可以使用 URLComponents
.
这个 class 操作 URL 非常方便。例如,它可以是 initialized using a URL
instance, and then list all the query parameters in an array via the queryItems
property.
Where I am stuck is testing the returned URL
.
URLComponents
也符合 Equatable
,因此您可以测试返回的 URL 值是否符合您的预期,如下所示:
- 创建一个
URLComponents
实例,配置了您期望的所有参数。这是测试的安排部分。
- 通过
asURL()
方法获取 URL 的值。这是测试的 act 部分。
- 使用刚刚得到的
URL
值创建一个新的 URLComponents
实例,然后将其与使用预期值构建的 URLComponents
进行比较,通过 XCTAssertEqual
for例子。这是测试的 assert 部分。
一旦你的所有测试都是绿色的,你可能想查看你的 Router
的实现,看看你是否也可以在其中使用 URLComponents
。此 class 由 Apple 提供,非常可靠。
我正在尝试使用 TDD 将 URL
单元化为 Swift。我想确保 URL
等于预期的 URL
。我正在使用 Router
enum
,使用 Alamofire
来创建我的 URL
。因此,作为 Router
enum
的 属性,我有一个 Dictionary<String,String>?
属性,因为我可能不需要其他 URL
的参数。但是,我确实需要用于身份验证的参数 URL
.
parameters
Dictionary<String,String>?
如下:
internal enum Router: URLConvertible {
internal static let baseURLString = "https://xxx.xxxxxx.xxx"
case authentication(clientID: String)
}
extension Router {
var pathString: String {
switch self {
case .authentication: return "xxxxx/xxxxx/xxxxxxxxx"
}
}
var method: HTTPMethod {
switch self {
case .authentication: return .get
}
}
var parameters: Dictionary<String, String>? {
switch self {
case .authentication(let clientID): return ["xxxxx": "xxxx", "client_id": clientID]
}
}
func asURL() throws -> URL {
switch self {
case .authentication:
return URL(string: "https://xxx.xxxxxx.xxx/xxxxx/xxxxx/xxxxxxxxx?xxxxx=xxxx&client_id=xxxxxxxxxx")!
}
}
}
到目前为止,我已经能够使用 TDD 方式成功编写所有代码。我卡住的地方是测试返回的 URL
。由于 parameters
是 Dictionary<String,String>?
类型,我想使用以下逻辑迭代 parameters
:
var parametersStringArray = Array<Dictionary<String,String>>()
for (key, value) in parameters {
// Create a parameter string from each set
// Something like the following:
let parameterString = String(describing: \(key)=\(value))
parametersStringArray.append(parameterString)
}
let parametersString = parametersStringArray.joined(separator: "&")
let fullURLString = baseURLString + "?\(parametersString)"
return URL(string: fullURLString)!
通过创建这样的参数,当我根据 asURL() throws -> URL
中的 Router
enum
返回的 URL
测试预期的 URL
时,它部分时间可能会失败,因为参数是在没有预期顺序的情况下添加到 URL
字符串中的。换句话说,如果我预期的 URL 是 https://xxx.xxxxxx.xxx?xxxxx=xxxx&client_id=xxxxxxxxxx
,它可以通过以相反的顺序返回参数来匹配或失败,如下所示:https://xxx.xxxxxx.xxx?client_id=xxxxxxxxxx&xxxxx=xxxx
.
对于我测试 URL
是否有更好的解决方案以确保当参数可以按任何顺序返回时返回正确的 URL
因为它们被添加到 URL
's string when iterates them?
我是否应该创建两个带有两种参数的 URL
s 并匹配任何一种?我认为不合适的原因是因为您拥有的参数越多,您必须创建越多的 URL
来进行测试。
我目前用于测试 URL
身份验证的测试如下:
import XCTest
import Alamofire
@testable import Projects
class AuthenticationURLTests: XCTestCase {
func test_API_BaseURLString_IsCorrect() {
let baseURLString = Router.baseURLString
let expectedBaseURLString = "https://xxx.xxxxxx.xxx/"
XCTAssertEqual(baseURLString, expectedBaseURLString, "Base URL does not match expected base URL. Expected base URLs to match.")
}
func test_API_OAuthPath_IsCorrect() {
let pathString = Router.authentication(clientID: "xxxxxxxxxx").pathString
let expectedPathString = "xxxxx/xxxxx/xxxxxxxxx"
XCTAssertEqual(pathString, expectedPathString, "Path string does not match expected path string. Expected path strings to match.")
}
func test_API_OAuthMethod_IsCorrect() {
let method = Router.authentication(clientID: "xxxxxxxxxx").method
let expectedMethod = HTTPMethod.get
XCTAssertEqual(method, expectedMethod, "HTTP methods do not match. Expected HTTP methods to match.")
}
func test_API_OAuth_ParametersContainsKeyForXXXXX() {
let scopeString = Router.authentication(clientID: "xxxxxxxxxx").parameters?["xxxxx"]
let expectedScopeString = "xxxx"
XCTAssertEqual(scopeString, expectedScopeString, "Scope strings do not match. Expected scope strings to match.")
}
func test_API_OAuth_ParametersContainsKeyForClientID() {
let clientID = Router.authentication(clientID: "12345abcde").parameters?["client_id"]
let expectedClientID_Fake = "12345abcde"
XCTAssertEqual(clientID, expectedClientID_Fake, "Client IDs do not match. Expected client IDs to match.")
}
func test_API_OAuth_URLIsCorrect() {
do {
let url = try Router.authentication(clientID: "12345abcde").asURL()
// Here, I want to ensure that the `URL`s match:
let expectedURL = URL(string: https://xxx.xxxxxx.xxx?xxxxx=xxxx&client_id=xxxxxxxxxx)!
} catch { XCTFail("Could not create URL for OAuth") }
}
}
对于所提供代码中的所有 x
,我们深表歉意。我想确保我没有提供任何关于我客户申请的信息。
你可以使用 URLComponents
.
这个 class 操作 URL 非常方便。例如,它可以是 initialized using a URL
instance, and then list all the query parameters in an array via the queryItems
property.
Where I am stuck is testing the returned
URL
.
URLComponents
也符合 Equatable
,因此您可以测试返回的 URL 值是否符合您的预期,如下所示:
- 创建一个
URLComponents
实例,配置了您期望的所有参数。这是测试的安排部分。 - 通过
asURL()
方法获取 URL 的值。这是测试的 act 部分。 - 使用刚刚得到的
URL
值创建一个新的URLComponents
实例,然后将其与使用预期值构建的URLComponents
进行比较,通过XCTAssertEqual
for例子。这是测试的 assert 部分。
一旦你的所有测试都是绿色的,你可能想查看你的 Router
的实现,看看你是否也可以在其中使用 URLComponents
。此 class 由 Apple 提供,非常可靠。