我有一个名为 AppleSignInAdapter 的接口适配器类,它将使用 Apple 的 AuthenticationServices。这是课程:
import AuthenticationServices
import RxSwift
enum AppleSignInError: Error {
case credentialsIncomplete
}
struct AppleSignInParam {
let authCode: String
let idToken: String
let email: String
@available(iOS 13.0, *)
init?(authorization: ASAuthorization) {
guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
let authCodeData = credential.authorizationCode,
let authCode = String(data: authCodeData, encoding: .utf8),
let idTokenData = credential.identityToken,
let idToken = String(data: idTokenData, encoding: .utf8),
let email = credential.email
else { return nil }
self.authCode = authCode
self.idToken = idToken
self.email = email
}
}
final class AppleSignInAdapter {
func handleSignIn() -> Observable<AppleSignInParam> {
if #available(iOS 13.0, *) {
let authController = createAuthController()
// didCompleteWithAuthorization and didCompleteWithError are functions from
// ASAuthorizationControllerDelegate that are implemented using RxCocoa's DelegateProxy
let authSuccessEvent = authController.rx
.didCompleteWithAuthorization
.compactMap { authorization -> AppleSignInParam? in
guard let param = AppleSignInParam(authorization: authorization) else {
throw AppleSignInError.credentialsIncomplete
}
return param
}
let authErrorEvent = authController.rx
.didCompleteWithError
.flatMapLatest { error -> Observable<AppleSignInParam> in
return .error(error)
}
let appleSignInEvent = authSuccessEvent.amb(authErrorEvent).take(1)
return appleSignInEvent
} else {
return .empty()
}
}
}
@available(iOS 13.0, *)
private func createAuthController() -> ASAuthorizationController {
let appleIdProvider = ASAuthorizationAppleIDProvider()
let request = appleIdProvider.createRequest()
request.requestedScopes = [.email]
let authController = ASAuthorizationController(authorizationRequests: [request])
authController.performRequests()
return authController
}
我在想如何为这个类做单元和集成测试。我被困在测试中,因为我无法真正模拟“使用 Apple 登录”的过程并手动触发委托(例如,如何测试成功、错误或AppleSignInError.credentialsIncomplete
错误)。还有一个事实是整个过程都是由 AuthenticationServices 处理的,所以我不能模拟输入本身。关于如何测试这个的任何想法?还是我应该只使用 UITest 来测试功能?
谢谢。