【问题标题】:Apple pay unit testing苹果支付单元测试
【发布时间】:2019-05-17 14:09:00
【问题描述】:

我正在使用 iOS 11 上的 Apple Pay

我对我们的信用卡标记化进行了单元测试。但我正在尝试标记一个苹果支付请求。

是否可以对 apple pay 进行单元测试?

import XCTest
import PassKit
@testable import os_ios

extension apiTests{
    func testBraintreeApplePay(){

        let expect = expectation(description: "testBraintreeApplePay")
        var responseReceived = false

        let number = "4111111111111111"
        let month = "12"
        let year = "20"
        let securityCode = "411"
        let postalCode = "70433"

        let payment = PKPayment()
        // add the above info to this payment


        Braintree.paymentAuthorizationViewController(
            didAuthorizePayment: payment,
            completion: {(status: PKPaymentAuthorizationStatus,nonce:String?) in

            responseReceived = true

            // Check to see if we've received a nonce

            expect.fulfill()
        })


        waitForExpectations(timeout: expectationTimeoutDuration, handler: nil)
        XCTAssert(responseReceived)
    }
}

【问题讨论】:

    标签: ios swift unit-testing applepay


    【解决方案1】:

    为了初始化“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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 2012-05-05
      • 2021-08-01
      • 2018-01-30
      • 1970-01-01
      • 2021-10-24
      • 2018-07-10
      相关资源
      最近更新 更多