Search code examples
iosunit-testingswiftalamofirenocilla

Stubbing HTTP Requests in Swift


I am using Swift for an iOS app, and using Alamofire to perform HTTP requests.

I want to write unit tests to cover my functions, but I'm having trouble stubbing the HTTP requests performed by Alamofire. I am using Nocilla (imported into bridging header) to try to stub my HTTP requests but it seems that the callback to my HTTP request never gets reached in the tests.

I was wondering if anyone has had any experience successfully stubbing HTTP requests for Alamofire in their test suites?

Thanks!


Solution

  • I haven't but this is the general pattern that I use for unit testing HTTP requests (calling REST APIs specifically). I've used this successfully for both Alamofire and AFNetworking.

    1. I normally have a class that "wraps" (let's call it Service) the underlying network APIs (Alamofire, AFNetworking, or just the pure iOS APIs). Service typically is stateless and is responsible for making the calls "nicer" for my application.
    2. For me, Service is typically closely related to the REST API I am trying to consume. For example, if I was using a REST API that allowed me to POST to a Person collection, I would have an API like Service.PostPerson, Service.GetPerson, etc.
    3. My application classes (typically the controllers) that use Service and typically use inversion of control to create Service.
    4. In my unit tests, I supply a UnitTestService so that my classes end up using an instance of UnitTestService instead of an instance of Service.
    5. To make things simple, my UnitTestService generally returns hard coded JSON responses based on configuration. So in the example above, I would have a hard coded JSON response for Service.PostPerson.

    I've used a number of techniques to do this:

    • Have a protocol ServiceProtocol that both Service and UnitTestService implement
    • Have a single Service that is instantiated with a set of closures. These closures do the real work, and you can supply different closures depending on whether you are connecting to the Internet or mocking it.

    Because I have some functional programming background, I like the latter. But both techniques work.