我正在尝试测试一段代码,我检查一下帐户是否已经创建了一个密钥并将其存储在钥匙串中。如果没有,它会调用一个启动oauth进程的方法。
如果用户没有密钥,我的第一个想法是覆盖我想要调用的方法。但是我使用的是结构,因此无法继承和覆盖该方法。
如果我使用的是课程,我会这样:
func testInitiateOauthCalledIfSecretKeyNotFound() {
class MockKeychainAccess: KeychainAccess {
var initiateAuthorizationWasCalled: Bool = false
override initiateAuthorization() {
initiateAuthorizationWasCalled = true
}
let keychainAccess = MockKeychainAccess()
keychainAccess.authorizeWithGoogle()
XCTAssertTrue(initiateAuthorizationWasCalled)
}
我没有测试过这段代码,所以不确定它是否编译。但从逻辑上讲,它似乎可以处理我追求的情况。如果我们在authorizeWithGoogle
方法中调用initiateAuthorization()
,那么我就知道已经发生了这种情况。但是,当他们使用结构时,我们无法继承结构,因此无法执行此操作。
请注意:我是TDD的新手,所以也许我正在考虑错误的方法。其他建议是受欢迎的。但是我不想只是为了编写测试而从结构转换为类。我正在使用结构,因为我试图更加迅速。
有没有人知道我可以测试是否在结构中调用函数的方法?
==========
修改
在回答dassm回答时,我正在添加一个我想要实现的一般方法的例子:
override func viewDidLoad() {
setupView()
let api = DataApi()
getData(api)
}
func setupView() {
tableView.dataSource = tableViewDataSource
}
func getData(api: DataApi) {
api.getApplicationData( { (objects) in
if let applications = objects as? [Application] {
self.tableViewDataSource.setApplicationItems(applications)
self.tableView.reloadData()
}
else {
// Display error
}
})
}
所以我想注入MockDataApi,以便它可以返回我想要的东西,因为该方法采用了一种DataApi。但是我不确定如何创建这个MockDataApi结构并将其传递给此方法。
有人可以帮助解决如何为此目的构建此模拟对象并使用它吗?我意识到这是协议,但很难将它拼凑在一起。
答案 0 :(得分:12)
使用协议。使您的类/结构和测试模拟符合协议。注入依赖项并声明在模拟中调用了预期的方法。
protocol DataApiProtocol {
func getApplicationData(block: [AnyObject] -> Void)
}
// Production code
struct DataApi: DataApiProtocol {
func getApplicationData(block: [AnyObject] -> Void) {
// do stuff
}
// more properties and methods
}
// Mock code
struct MockDataApi: DataApiProtocol {
var getApplicationDataGotCalled = false
func getApplicationData(block: [AnyObject] -> Void) {
getApplicationDataGotCalled = true
}
}
// Test code
func testGetData_CallsGetApplicationData() {
let sut = MyAwesomeClass()
let mockDataApi = MockDataApi()
sut.getData(mockDataApi)
XCTAssertTrue(mockDataApi.getApplicationDataGotCalled)
}
我希望这会有所帮助。