XCTestCase检查是否在Struct中调用了一个方法

问题描述 投票:10回答:1

我正在尝试测试一段代码,我检查一下帐户是否已经创建了一个密钥并将其存储在钥匙串中。如果不是,则调用启动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结构并将其传递给此方法。

有人可以帮助解决如何为此目的构建这个模拟对象并使用它吗?我意识到这是协议,但很难将它拼凑在一起。

ios swift struct xctest xctestcase
1个回答
16
投票

使用协议。使您的类/结构和测试模拟符合协议。注入依赖项并声明在mock中调用了预期的方法。

编辑:示例

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)
}

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.