Mocking Network Calls in Swift

Yes, you can test your code without making genuine network calls

Prerequisites:

Terminology

The use of mocking

Step by Step Code allowing Testability

Downloading from a URL

Theory: A data task to download

Create a simple function to download data

downloadData(URLSession.shared)

Simple testing

Mocking URLSession through different methods

Subclassing URLSession

The problem with subclassing

Failed Attempt 1: Mock URLSession, conforming to a protocol and Mock DataTaskMock

protocol URLSessionProtocol {
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
}
extension URLSession: URLSessionProtocol {}
protocol URLSessionDataTaskProtocol {
func resume()
}

Method 2: Mock URLSession, subclass DataTask

Method 3: Mock URLSession, Mock DataTask

protocol URLSessionProtocol {
associatedtype dta: URLSessionDataTaskProtocol
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> dta
}
protocol URLSessionDataTaskProtocol {
func resume()
}
class MockNetworkCallsTests: XCTestCase {
func testUsingSimpleMock() {
let mockSession = URLSessionMock()
mockSession.data = "testData".data(using: .ascii)
let exp = expectation(description: "Loading URL")
let vc = ViewController()
vc.downloadData(mockSession, completionBlock: {data in
exp.fulfill()
})
waitForExpectations(timeout: 0.1)
}
}

Repo

Conclusion:

The Twitter contact:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store