使用 OHHTTPStubs 模拟时未达到 Alamofire 响应块

Posted

技术标签:

【中文标题】使用 OHHTTPStubs 模拟时未达到 Alamofire 响应块【英文标题】:Alamofire response block not reached when mocking with OHHTTPStubs 【发布时间】:2018-06-06 13:51:36 【问题描述】:

当我运行应用程序时,到达 Alamofire 响应块没有问题。当使用 OHHTTPStubs 运行测试和模拟响应时,两个存根块(请求和响应)都会被调用,但 Alamofire 响应块永远不会被调用,因此测试失败。 用 URLRequest 尝试了完全相同的存根,响应块被称为没有问题。

API 类:

private static var config: URLSessionConfiguration?
private static var session: SessionManager?

static var instance = getInstance()

private static func getInstance() -> Api 
    let api = self.init()
    return api


private init() 
    Api.config = URLSession.shared.configuration
    var headers = SessionManager.defaultHTTPHeaders
    headers.removeValue(forKey: "User-Agent")
    headers["User-Agent"] = APP_VERSION
    Api.config?.httpAdditionalHeaders = headers
    Api.session = SessionManager(configuration: Api.config!)


func requestFunction(_ path: String) 
    let req = Api.session!.request("\(apiUrl())\(path)", method: .get, parameters: request.toJSON()).response(completionHandler: completionHandler)

测试:

func test() 
    stub(condition:  (request) -> Bool in
            return true
        )  (request) -> OHHTTPStubsResponse in
            return OHHTTPStubsResponse(
                jsonObject: self.usageResponse,
                statusCode: 200,
                headers: ["Content-Type":"application/json"]
            )
        

    let semaphore = DispatchSemaphore.init(value: 0)
    Api.instance.requestFunction(path,  (_, _) in
        semaphore.signal()
    )

    let timeout = DispatchTime.now() + DispatchTimeInterval.seconds(300)
    if semaphore.wait(timeout: timeout) == DispatchTimeoutResult.timedOut 
        XCTFail("semaphore not reached")
    

从未达到信号量。但是,如果我不调用 Alamofire 而不是这样做,那么信号量就没有问题了:

    do 
        let request = try URLRequest.init(url: "www.w.com", method: .post)
        let configuration = URLSessionConfiguration.default
        let session = URLSession(configuration: configuration)
        let task = session.dataTask(with: request)  (_, _, _) in
            semaphore.signal()
        
        task.resume()
     catch 

    

【问题讨论】:

requestFunction 方法没有任何闭包。你确定你使用的是test()中的方法吗? 【参考方案1】:

不确定你在某处打电话给Api.instance。但似乎您没有使用 Api 类的共享实例,但您正在初始化 private init() 方法中的所有内容。

class Api 
    private var config: URLSessionConfiguration?
    private var session: SessionManager?

    static let shared = Api()

    private init() 
        config = URLSession.shared.configuration
        var headers = SessionManager.defaultHTTPHeaders
        headers.removeValue(forKey: "User-Agent")
        headers["User-Agent"] = APP_VERSION
        config?.httpAdditionalHeaders = headers
        session = SessionManager(configuration: Api.config!)
    

    func requestFunction(_ path: String) 
        let req = session!.request("\(apiUrl())\(path)", method: .get, parameters: request.toJSON()).response(completionHandler: completionHandler)
    

测试应该是

func test() 
    ...

    Api.shard.requestFunction(path,  (_, _) in
        semaphore.signal()
    )

    ...

【讨论】:

对不起。我正在使用实例,我只是将它错误地复制到*** getInstance() 方法有什么用?可以在原题中添加代码吗? 刚刚添加了getInstance方法。感谢您的耐心

以上是关于使用 OHHTTPStubs 模拟时未达到 Alamofire 响应块的主要内容,如果未能解决你的问题,请参考以下文章

OHHTTPStubs 单元测试实现

让 Alamofire 和 OHHTTPStubs 一起工作

未找到“OHHTTPStubs/OHHTTPStubs.h”文件

在 Swift 中使用 OHHTTPStubs 测试请求正文

Swift:OHHTTPStubs 的测试实现显示错误

在真实设备模式下模拟或运行时未处理 http 请求,但在模拟器上运行良好