Chapters

Hide chapters

iOS Test-Driven Development by Tutorials

Second Edition · iOS 15 · Swift 5.5 · Xcode 13

8. RESTful Networking
Written by Joshua Greene

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In this chapter, you’ll learn how to TDD a RESTful networking client. Specifically, you’ll:

  • Set up the networking client.
  • Ensure the correct endpoint is called.
  • Handle networking errors, valid responses and invalid responses.
  • Dispatch results to a response queue.

Get excited! TDD networking awesomeness is coming your way.

Getting started

Navigate to the starter directory for this chapter. You’ll find it has a DogPatch subdirectory containing DogPatch.xcodeproj. Open this project file in Xcode and take a look.

You’ll see a few files waiting for you. The important ones for this chapter are:

  • Controllers/ListingsViewController.swift displays the fetched Dogs or Error.

  • Models/Dog.swift is the model that represents each pup.

  • Networking is an empty folder for now. You’ll add the networking client and related types here.

Build and run the app, and the following error-message screen will greet you:

If you pull down to refresh, the activity indicator will animate but won’t ever finish.

Open ListingsViewController.swift. You’ll see tableView(_:numberOfRowsInSection:) returns the max of viewModels.count or one, if it isn’t currently refreshing.

Similarly, tableView(_:cellForRowAt:) checks if viewModels.count is greater than zero, which will always be false because the app isn’t setting viewModels right now. Rather, you need to create these from a network response.

However, there’s a comment for // TODO: Write this within refreshData(), so the app isn’t making any network calls…

Your job is now clear! You need to write the logic to make networking calls. While you could make a one-off network call directly within ListingsViewController, this view controller would quickly become very large.

A better option is to create a separate networking client that handles all of the networking logic, which happens to be the focus of this chapter!

Setting up the networking client

Before you write any production code, you first need to write a failing test.

TDDing the networking call

You need to make a GET request to fetch a list of Dog objects from the server. You’ll break this down into several smaller tasks:

Mocking URLSession

To keep your tests fast and repeatable, don’t make real networking calls in them. Instead of using a real URLSession, you’ll create a MockURLSession that will let you verify behavior but won’t make network calls. You’ll pass this into the initializer for DogPatchClient and use it like you’d use a real URLSession.

Creating the session protocols

Within DogPatch/Networking, create a new Swift File called URLSessionProtocol.swift and replace its contents with:

Conforming to the session protocols

You next need to make URLSession conform to URLSessionProtocol, and URLSessionTask conform to URLSessionTaskProtocol. Because URLSessionProtocol uses URLSessionTaskProtocol, start by making URLSessionTask conform first.

Creating and using the session mocks

Next, you need to create test types for MockURLSession and MockURLSessionTask.

Calling the right URL

Now, use MockURLSession to validate behavior within your tests!

Handling error responses

Next, you need to handle error responses. Two scenarios indicate an error occurred:

Deserializing models on success

You’re finally ready to handle the happy-path case: handling a successful response.

Dispatching to a response queue

Your DogPatchClient handles networking like a boss! There’s just one problem: You’ve been mocking URLSessionTask to avoid making real networking calls, but unfortunately, you’ve also masked a behavior of URLSessionTask.

Adding a response queue

Add the following test right after test_init_sets_session(), ignoring the compiler error for now:

Updating the mocks

Next, you need to update MockURLSession and MockURLSessionTask to call the completion handler on a dispatch queue. In MockURLSession.swift, add this new property to MockURLSession:

Handling dispatch scenarios

Next, you need to verify that completionHandler dispatches to the responseQueue, which should happen in these cases:

Key points

In this chapter, you learned how to do TDD for a networking client. Here’s a recap of what you learned:

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now