Testing NSURLSession With Swift
Ideally, the interface to
NSURLSession
would be protocol based. We could create a mock object that conformed to this protocol and use the objects interchangeably under test.Unfortunately, Apple hasn’t fully embraced protocol-oriented programming in its framework code. No worries; we’ll create our own protocol, and have
NSURLSession
conform to it via an extension.[…]
We don’t actually have to implement anything in this extension because we kept the method signature the same as Apple’s framework. Meaning,
NSURLSession
already implements our protocols required methods.[…]
The error is occurring because
NSURLSession
doesn’t have adataTaskWithURL()
method that returns our custom protocol. To fix this, we just need to extend the class a little differently.[…]
Here we implement the method in the protocol manually. But instead of doing any actual work, we call back to the original implementation and cast the return value. The cast doesn’t need to be implicit because our protocol already conforms to Apple’s data task.
This is a subtle bit of code where the protocol and class have methods with the same name and arguments but different return types. So it’s an overload rather than an override.
To keep our tests running fast let’s completely flatten the code path. One thread, no asynchronous behavior, no network activity.
[…]
Now we can set what data and/or error is returned from the
dataTaskWithURL()
method. But wait, that method returns a data task, right? Correct, but look at the last parameter.The completion handler would normally be called by the API when a real network request returns. We need to replicate this while we build our own mock. To do so, simply call the handler with our “next” variables before returning.
Previously: Swift Protocols.
Update (2016-11-12): Part 3.