swift - 使用备用数据创建 Swift HTTP 模拟

标签 swift xctest

我有一个模拟的 HTTPManager,我希望它返回 userIDResonse 或 tokenResponse。

为了能够做到这一点,我使模拟符合协议(protocol),以允许在测试中进行设置。

let userIDResponse = """
{\"user_id\":\"5a7ab957a225856b38f49bb4\"}
"""

let tokenResponse = """
{\"access_token\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjczMUE3OUEyMjY3QjY4Q0EwNTc5QjYzRjdFMkY0QjlBQkZFMENEMTUiLCJ0eXAiOiJKV1QiLCJ4NXQiOiJjeHA1b2laN2FNb0ZlYllfZmk5TG1yX2d6UlUifQ.eyJuYmYiOjE1MTI5NjU3NTgsImV4cCI6MTUxMjk2OTM1OCwiaXNzIjoiaHR0cHM6Ly9pZG0uYWxwaGFub3ZhLnNnIiwiYXVkIjpbImh0dHBzOi8vaWRtLmFscGhhbm92YS5zZy9yZXNvdXJjZXMiLCJhcGkyIl0sImNsaWVudF9pZCI6ImNhcGFwb3QtbmciLCJzdWIiOiI1YTFjMWU5MjY0MjUzYjFlMWU2N2ZhZDIiLCJhdXRoX3RpbWUiOjE1MTI5NjU3NTgsImlkcCI6ImFscGhhbm92YSIsImZpcnN0X25hbWUiOiJTdGV2ZW4iLCJsYXN0X25hbWUiOiJDdXJ0aXMiLCJuYW1lIjoiU3RldmVuIEN1cnRpcyIsImVtYWlsIjoic3RldmVuQGFscGhhbm92YS5zZyIsInNjb3BlIjpbImNhcGFwb3QucHJvZmlsZSIsImVtYWlsIiwib3BlbmlkIiwiYXBpMi5yZWFkX29ubHkiLCJvZmZsaW5lX2FjY2VzcyJdLCJhbXIiOlsicGFzc3dvcmQiXX0.q4-SF5KBVSwN4bFhcQ88icR9X2jzz_JH2K4EpDgS-oZjjppNruckxfTjauVqcwG8zPR0eGzx5CBXiAfMeg9akShWajqBZ9rkCsqjXw6Ef74J9cTBDhxTEUL0v7P0zm_fVNOutM_UJQ-DiQr2gAO0mfAxMhOiQ_uXlKoM2RYGKjfMkH6Ym7kBjtRAhho8pPVmtQiBmVFI5OUVXNU3rPVgB7sx-I1LZmUZBZoy7T4s14TAuE4yiUyTBgO5joyRsZtMdFybna8CRK_ylS3WC6wOBNm74O9IrZlbsiradtLzMG-9E8AnjbvH4RYR68H2xpt562PfnGD_VC9NXFQ7iRrRMw\"}
"""

由模拟使用

protocol HTTPManagerMockProtocol {
    func setResponse(response: String.UTF8View)
}

typealias HTTPMock = HTTPManagerProtocol & HTTPManagerMockProtocol

class HTTPManagerMock: HTTPMock {

    var data = Data(userIDResponse.utf8)

    func setResponse(response: String.UTF8View) {
        data = Data(response)
    }

    func get(urlString: String, parameters: [String : String], completionBlock: @escaping (Result<Data, Error>) -> Void) {
        completionBlock(.success(data))
    }

}

所以在我的测试中我必须设置响应:

let httpMock = HTTPManagerMock()
httpMock.setResponse(response: tokenResponse.utf8)
sut = Login(serverString: "serverURL", headers: [:], httpManager: httpMock )

在某些方面,这似乎没问题,但这意味着我无法在测试中使用设置函数,这会导致我的测试类中出现重复的代码。

哪种方法意味着我可以拥有具有不同输出的模拟,而无需生成额外的测试代码?

最佳答案

创建参数化辅助方法来创建您的被测系统。

private func makeLogin(response: String) -> Login {
    let httpMock = HTTPManagerMock()
    httpMock.setResponse(response: response.utf8)
    return Login(serverString: "serverURL", headers: [:], httpManager: httpMock)
}

这样,您就可以改变不同测试的响应。如果您进行的测试并不真正关心响应并希望提供虚拟数据,那么这可以是帮助程序中的默认值。

关于swift - 使用备用数据创建 Swift HTTP 模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57651872/

相关文章:

ios - 如何将 UIBarButtonItem 放在 Swift4 上的 NavigationController 的 ViewController 上?

ios - 我的应用程序因 heightConstraints 而崩溃我不知道如何修复

swift 。从 Int 获取 Int 的最佳方式?

Xcode 10和super.tearDown

ios - 如何在 Xcode 的 UI 测试类目标中包含 SwiftyUserDefaults.swift?

ios - 为什么我应该使用单独的测试主机来运行 XCTests,我应该怎么做?

iphone - 有没有一种方法可以在一次更新所有 UIControlStates 的 UIButton 上设置标题?

ios - 如何在 Swift 中使用邮件黑猩猩发送即时电子邮件?

iOS:xcode 5,将项目从 xctest 迁移到 senTestingKit

ios - 使用Swift和XCTest修改私有(private)数组的测试方法