davi albuquerque
davi albuquerque

Reputation: 46

Alamofire response block not reached when mocking with OHHTTPStubs

When I run the app the Alamofire response block is reached no problem. When running tests and mocking the response with OHHTTPStubs both stub blocks (request and response) are called but the Alamofire response block is never called so the tests fail. Tried the exact same stub with URLRequest and the response block is called no problems.

Api class:

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

Test:

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

Semaphore is never reached. But if instead of calling Alamofire I do this the semaphore is reached no problem:

    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 {

    }

Upvotes: 0

Views: 401

Answers (1)

Ryan
Ryan

Reputation: 4884

Not sure you called Api.instance somewhere. But seems you are not using the shared instance of Api class but you are initializing everything in the private init() method.

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

And the test should be

func test() {
    ...

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

    ...
}

Upvotes: 0

Related Questions