If you didn’t work through Chapter 12, Testing Network Requests (with Mocks), the full-fledged mock object we developed would be a confusing starting point for learning closure techniques. To simplify this example, let’s set that MockURLSession aside and start over with a fresh test spy. (If you’re continuing with last chapter’s code, when you see NetworkResponse or NetworkResponseTests below, mentally convert to NetworkRequest and NetworkRequestTests.)
Select the NetworkResponseTests group in the Project Navigator and press ⌘-N to make a new file. Click the iOS selector at the top, select Swift File, and press Next. In the dialog, enter SpyURLSession.swift as the name of the file. In the Save dialog, double-check that the test target is selected, not the app target. Press Create and enter the following code:
| @testable import NetworkResponse |
| import Foundation |
| |
| private class DummyURLSessionDataTask: URLSessionDataTask { |
| override func resume() { |
| } |
| } |
| |
| class SpyURLSession: URLSessionProtocol { |
| } |
Xcode will show a Swift error:
| Type 'SpyURLSession' does not conform to protocol 'URLSessionProtocol' |
In the Xcode menu, select Editor ▶ Fix All Issues. Xcode will generate a stub for the protocol method. Fill in the rest as shown here to increment the call count, capture the arguments, and return a DummyURLSessionDataTask:
| var dataTaskCallCount = 0 |
| var dataTaskArgsRequest: [URLRequest] = [] |
» | var dataTaskArgsCompletionHandler: |
» | [(Data?, URLResponse?, Error?) -> Void] = [] |
| |
| func dataTask( |
| with request: URLRequest, |
| completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void |
| ) -> URLSessionDataTask { |
| dataTaskCallCount += 1 |
| dataTaskArgsRequest.append(request) |
» | dataTaskArgsCompletionHandler.append(completionHandler) |
| return DummyURLSessionDataTask() |
| } |
This is identical to Make a Test Spy except that now we’re capturing the completionHandler argument.