为了初始化“PKPaymentAuthorizationController”,您需要注入每个特定测试所需的值。在 Apple Pay 的情况下,它通常涉及方法 'canMakePayments(usingNetworks: [PKPaymentNetwork]) -> Bool' 和 'PKPaymentAuthorizationController' 或 'PKPaymentAuthorizationViewController' 的可失败初始化程序。
您可以通过构造函数注入(在初始化程序上传递值)或属性注入来实现。
这是一个处理授权控制器初始化的类的示例,并以控制器完成,或以错误完成。
public class PaymentAuthorizationHandler {
public typealias ApplePayControllerFactory = (PKPaymentRequest) -> PKPaymentAuthorizationViewController?
public typealias ApplePayCompletionHandler = (Result<PKPaymentAuthorizationViewController, Error>) -> Void
public typealias NetworkAuthorizationHandler = ([PKPaymentNetwork]) -> Bool
public enum Error: Swift.Error {
case networkNotSupported
case unableToInitialize
}
private let controllerFactory: ApplePayControllerFactory
private let networkAuthorizationHandler: NetworkAuthorizationHandler
public init(
controllerFactory: @escaping ApplePayControllerFactory = PKPaymentAuthorizationViewController.init,
networkAuthorizationHandler: @escaping NetworkAuthorizationHandler = PKPaymentAuthorizationViewController.canMakePayments
) {
self.controllerFactory = controllerFactory
self.networkAuthorizationHandler = networkAuthorizationHandler
}
private func makeRequest() -> PKPaymentRequest { //... }
public func requestAuthorization(completion: ApplePayCompletionHandler) {
let request = makeRequest()
guard networkAuthorizationHandler(request.supportedNetworks) else {
completion(.failure(.networkNotSupported))
return
}
guard let paymentVC = controllerFactory(request) else {
completion(.failure(.unableToInitialize))
return
}
completion(.success(paymentVC))
}
}
视图控制器初始化程序和“canMakePayments(usingNetworks: [PKPaymentNetwork]) -> Bool”方法签名正在通过构造函数注入注入,由类型别名表示。通过此更改,可以在生产中传递真实方法,并且对于测试使用,可以通过在测试设置期间注入来提供测试用例所需的值。
这是一个测试示例:
func test_requestAuthorization_failsWhenControllerInitializationFails() {
let authController = PKPaymentAuthorizationViewController(paymentRequest: .invalidRequest)
let sut = PaymentAuthorizationHandler(controllerFactory: { request in
authController
}, networkAuthorizationHandler: { networks in
true
})
let exp = expectation(description: "Wait for request permission")
var expectedError: PaymentAuthorizationHandler.Error?
sut.requestAuthorization { response in
switch response {
case let.success(controller):
XCTFail("Expected failure, received \(String(describing: controller)) instead")
case let .failure(receivedError):
expectedError = receivedError
}
exp.fulfill()
}
wait(for: [exp], timeout: 1.0)
XCTAssertEqual(expectedError, .unableToInitialize)
}
func test_requestAuthorization_succeedsWhenPaymentNetworkSupported() {
let authController = PKPaymentAuthorizationViewController(paymentRequest: .validRequest)
let sut = PaymentAuthorizationHandler(controllerFactory: { request in
authController
}, networkAuthorizationHandler: { networks in
true
})
let exp = expectation(description: "Wait for request permission")
sut.requestAuthorization { response in
switch response {
case let.success(receivedController):
XCTAssertNotNil(receivedController, "Request might be incomplete, or payment is not possible")
case let .failure(receivedError):
XCTFail("Expected success, received \(receivedError) instead")
}
exp.fulfill()
}
wait(for: [exp], timeout: 1.0)
}
您可以查看更详尽的解释here。