我试图为我的单元测试创建一个假身份验证器,可以手动将用户设置为登录或注销,并绕过我的代码实际使用的API,我需要一个真正的accessToken来记录用户在。
我已将我的应用使用的身份验证API包装到以下类中:
API Wrapper
import OIDC
protocol Authenticator {
func getValidAccessToken(completionHandler: @escaping (Error?, String?) -> Void)
}
struct OIDCAuthenticator: Authenticator {
func getValidAccessToken(completionHandler: @escaping (Error?, String?) -> Void) {
//API call
OIDCHelper.getValidAccessToken { (error, accessToken) in
DispatchQueue.main.async {
completionHandler( error, accessToken)
}
}
}
}
然后我使用相同的协议创建一个虚假身份验证器以进行测试
假/测试身份验证器
import OIDC
import Foundation
///Mocks the user being logged in our logged out for Testing purposes
struct FakeAuthenticator: Authenticator {
let error: OIDCError?
let accessToken: String?
func getValidAccessToken(completionHandler: @escaping (Error?, String?) -> Void) {
completionHandler(error, accessToken)
}
init(loggedIn: Bool) {
if loggedIn {
error = .tokenNotFoundInKeychainData
accessToken = nil
} else {
error = nil
accessToken = "abcdefg"
}
}
}
在OIDCAuthenticator
子类中设置身份验证器时,ViewController
API包装器设置正常。
TableViewController实施
import UIKit
import OIDC
class SettingsPageTableViewController: UITableViewController{
// MARK: - Outlets and variables
var authenticator: Authenticator!
private var isUserLoggedIn = false
// MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
authenticator = OIDCAuthenticator()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
authenticator.getValidAccessToken { [weak self] (error, _) in
self?.isUserLoggedIn = (error == nil)
self?.setLogginStatus()
}
}
}
但是当我尝试在我的单元测试中对FakeAuthenticator
做同样的事情时,我收到以下错误:
SettingsViewController测试类
import XCTest
import UIKit
@testable import MyProject
class SettingsViewControllerTests: XCTestCase {
var viewController: SettingsPageTableViewController!
override func setUp() {
super.setUp()
configureViewControllerForTesting()
}
private func configureViewControllerForTesting() {
let storyboard = UIStoryboard(name: "SettingsPage", bundle: nil)
let navigationController = storyboard.instantiateInitialViewController() as! UINavigationController
viewController = navigationController.topViewController as! SettingsPageTableViewController
_ = viewController.view
}
func testSignInButtonIsAvailableWhenUnauthenticated() {
viewController.authenticator = FakeAuthenticator(loggedIn: false)
}
}
当我用FakeAuthenticator
换出OIDCAuthenticator
时,会发生同样的事情。我还尝试将FakeAuthenticator
转换为Authenticator
,但这只会将错误更改为Cannot assign value of type 'Authenticator' to type 'Authenticator!'.
为什么我会收到此错误,解决此问题的最佳方法是什么?
答案 0 :(得分:1)
您需要从测试目标中删除文件,因为您已经使用@testable导入了整个项目。