我终于找到了一种方法来模拟这个火场
Auth
对象对我来说是必要的,但是我不得不使用Firebase的子类
User
对象,在测试期间向其添加新属性(无法创建
用户
对象,然后创建符合
FirebaseAuthDataResultType
MockUser
测试期间的对象。我最终需要的协议和扩展如下:
protocol FirebaseAuthDataResultType {
var user: User { get }
}
extension AuthDataResult: FirebaseAuthDataResultType {}
typealias FirebaseAuthDataResultTypeCallback = (FirebaseAuthDataResultType?, Error?) -> Void
protocol FirebaseAuthenticationType {
func signIn(withEmail email: String, password: String, completion: FirebaseAuthDataResultTypeCallback?)
func signOut() throws
func addStateDidChangeListener(_ listener: @escaping AuthStateDidChangeListenerBlock) -> AuthStateDidChangeListenerHandle
func removeStateDidChangeListener(_ listenerHandle: AuthStateDidChangeListenerHandle)
}
extension Auth: FirebaseAuthenticationType {
func signIn(withEmail email: String, password: String, completion: FirebaseAuthDataResultTypeCallback?) {
let completion = completion as AuthDataResultCallback?
signIn(withEmail: email, password: password, completion: completion)
}
}
class MockUser: User {
let testingUID: String
let testingEmail: String?
let testingDisplayName: String?
init(testingUID: String,
testingEmail: String? = nil,
testingDisplayName: String? = nil) {
self.testingUID = testingUID
self.testingEmail = testingEmail
self.testingDisplayName = testingDisplayName
}
}
struct MockFirebaseAuthDataResult: FirebaseAuthDataResultType {
var user: User
}
带有存根的模拟Firebase身份验证服务的实例:
class MockFirebaseAuthenticationService: FirebaseAuthenticationType {
typealias AuthDataResultType = (authDataResult: FirebaseAuthDataResultType?, error: Error?)
var authDataResultFactory: (() -> (AuthDataResultType))?
func signIn(withEmail email: String, password: String, completion: FirebaseAuthDataResultTypeCallback?) {
// Mock service logic goes here
}
// ...rest of protocol functions
}
RxSwift
和
RxTest
):
func testLoginUserReturnsUserIfSignInSuccessful() {
let firebaseAuthService = MockFirebaseAuthenticationService()
let expectedUID = "aM1RyjpaZcQ4EhaUvDAeCnla3HX2"
firebaseAuthService.authDataResultFactory = {
let user = MockUser(testingUID: expectedUID)
let authDataResult = MockFirebaseAuthDataResult(user: user)
return (authDataResult, nil)
}
let sut = UserSessionRepository(authenticationService: firebaseAuthService)
let userObserver = testScheduler.createObserver(User.self)
sut.loginUser(emailAddress: "john@gmail.com", password: "123456")
.bind(to: userObserver)
.disposed(by: disposeBag)
testScheduler.start()
let user = userObserver.events[0].value.element as? MockUser
// Assert MockUser properties, events, etc.
}
如果有人对如何实现这一点有更好的想法,请告诉我!