How to effectively verify unit test side effect without code generation in Swift

Thanks to Bill Chung for the wonderful eye animation

Often we need to unit test code with side-effects that interact with other parts of your system using abstraction — protocols in Swift. There are many techniques to build that abstraction and verify if our code works as expected: stubbing, spying, dummying etc.

Previously, I made a deep dive into auto-generating a stub placeholder that allows seamless customization of a mock’s function behavior right in a test case. Let’s extend that approach with a spy registration that observes and records side-effects generated during a test case.

What you need to know first

Let me present in a nutshell how you can speed up a process of…

Unit tests and memory leaks

How do you assert that your code doesn’t introduce any unexpected cycles that lead to memory leaks? Do you actually verify weak/strong references in unit tests? If you find these questions interesting, let me demonstrate how you can write a concise and self-explanatory Swift test case that verifies correct reference type.

Weak verification

Whether your code keeps a strong or weak reference to some other object is crucial for non-garbage-collected languages like Swift. Even a tiny mistake may lead to a leak, invalid behavior or even crash. Although I don’t see many developers writing them, I believe that verification on a unit…

Build Rules to select a file variant

If you want to configure your iOS/Mac (Swift or Objective-C) build with some alternative variant, there are plenty of different approaches to follow. In general, you can divide them into two clusters: switch it in runtime (e.g. parsing Info.plist) or compile-time (leveraging Swift Compilation Conditions/Preprocessor Macro or define new target). Obviously, we always prefer the compile-time check but the overhead often may overweight its benefits.

This post will present an alternative way to control a file variant selection based on Xcode Build Rules (in contrast to traditional Xcode targets).

Problem statement

There are plenty of solutions to build a different flavor of…

How to quickly write unit test stub in Swift without code generation

Often we need to unit test a code with side-effects that interact with other parts of your system by abstraction— protocols in Swift. There are many ways to verify if it works as expected: stubbing, spying, dummying etc. In general, engineers dubbed these forms as mocks, even “test double” is a legit name for that.

FYI, “test double” name comes from “stunt double” in the film industry.

Writing test doubles (like stubs or mocks) is a boring process in Swift and developers often try to generate it automatically by using tools like Sourcery/SwiftyMocky. …

We all love protocol extensions, one of the most powerful element of protocol oriented programming (POP) in Swift. Despite their unquestionable benefits, there are some rare cases where you should avoid them. In this article, let me demonstrate a potential trap that your API consumer may fall into when trying to unit test a code that depends on some protocol extension function.

Quick reminder: method dispatching

In Swift we have three kinds of method dispatching: static, vtable and message dispatching. If you are not familiar with this terms, let me recommend a great post from Riazlab’s. In short, dispatching methods…

How to handle errors in iOS apps

There isn’t a lot of articles about error handling in the iOS ecosystem, even this seems to be a non easy and substantial component of each app. Today, I wish to tackle this problem and present my solution towards less disruptive error handling in the iOS app.

Initial state

To ensure that we are on the same page, by an error I will mean an instance that conforms to Swift’s Error type and error handling is a reaction to it. These errors may arrive in a synchronous manner (disk operations, invalid argument) or asynchronously (no Internet connection, session token invalidated etc.). First…

Practicing TDD using Xcode IDE can be a bit disruptive. Every time you introduce a small change in the implementation or test file, Xcode rebuilds entire project (fortunately using incremental build) and installs the app on a simulator. Depending which project configuration you have, it may take from a few to dozens of seconds. This article presents a way to bypass this long lasting procedure and automatically run unit test(s) whenever you save your implementation .swift file. We will leverage new feature of John Holdsworth’s “Injection for Xcode” app — support for auto-testing.

InjectionTDD (together with InjectionForXcode) runs unit…

How to test non-called completion handler scenario

Testing completion-handler API happy path scenario is really simple with XCTestExpectation. Things get complicated if your test case has to verify whether given handler was not called. It is still straightforward if it’s called synchronously after some other event that you emulate. But how about a case where execution is deferred in time? In this article, I will demonstrate you a solution to achieve 100% sure that given completion handler will never be called — fast and reliable.

Problem statement

Let’s talk about unit tests of some asynchronous task that provides completion handler — let’s…

Safety over simplicity

Swift language was designed with a focus on “safe by default” approach (do not confuse with “safe by design” — Swift does not prevents you from doing dangerous actions but only encourages for good practices). One of such incentive is a great support for sum and product data types, enum and struct, respectively. These types are great to limit number of potential states during compilation time so we don’t have to write any unit tests of cases that should never occur — you definitely prefer to never reach given state, rather than covering it with an obvious unit test.

Problem statement


Bartosz Polaczyk

iOS Engineer at Spotify

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