Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test request body with OHHTTPStubs in Swift

I'm trying to test the request body sent captured with OHHTTPStubs but it seems buggy returning because the request.httpBody is nil.

I found this info about this problem Testing for the request body in your stubs. But I'm pretty new in iOS development and don't know how to access to OHHTTPStubs_HTTPBody in Swift. How can I do this?

like image 332
Addev Avatar asked May 20 '17 11:05

Addev


2 Answers

I guess rough equivalent in Swift will be following:

import OHHTTPStubs.NSURLRequest_HTTPBodyTesting
...
stub(isMethodPOST() && testBody()) { _ in
  return OHHTTPStubsResponse(data: validLoginResponseData, statusCode:200, headers:nil)
}).name = "login"

public func testBody() -> OHHTTPStubsTestBlock {
  return { req in 
    let body = req.ohhttpStubs_HTTPBody()
    let bodyString = String.init(data: body, encoding: String.Encoding.utf8)

    return bodyString == "user=foo&password=bar"
  }
}

So, more precisely, you can access OHHTTPStubs_HTTPBody by calling ohhttpStubs_HTTPBody() method inside OHHTTPStubsTestBlock.

like image 132
Anton Malmygin Avatar answered Oct 23 '22 17:10

Anton Malmygin


What worked for me is the following:

func testYourStuff() {

    let semaphore = DispatchSemaphore(value: 0)

    stub(condition: isScheme(https)) { request in
        if request.url!.host == "blah.com" && request.url!.path == "/blah/stuff" {

            let data = Data(reading: request.httpBodyStream!)
            let dict = Support.dataToDict(with: data)

            // at this point of time you have your data to test
            // for example dictionary as I have
            XCTAssertTrue(...)

        } else {
            XCTFail()
        }

        // flag that we got inside of this block
        semaphore.signal()

        return OHHTTPStubsResponse(jsonObject: [:], statusCode:200, headers:nil)
    }

    // this code will be executed first,
    // but we still need to wait till our stub code will be completed
    CODE to make https request

    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
}

// convert InputStream to Data
extension Data {

init(reading input: InputStream) {

    self.init()
    input.open()

    let bufferSize = 1024
    let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
    while input.hasBytesAvailable {
        let read = input.read(buffer, maxLength: bufferSize)
        self.append(buffer, count: read)
    }
    buffer.deallocate(capacity: bufferSize)

    input.close()
  }
}

Credits to this person for converting InputStrem to Data: Reading an InputStream into a Data object

like image 31
Eugene Avatar answered Oct 23 '22 16:10

Eugene