When you are starting out on testing your code, you might find asynchronous methods a little bit tricky to test.

But do not worry, XCTestExpectation got you covered if you want to assert that an async block will execute, or even assert that it will not execute.

In this post, I’ll show you a really common case where you’ll want to test an asynchronous method, and how to use XCTestExpectation to create an expectation that a block will be executed on the future, and how to create an inverted expectation to assert that a block will not be executed on the future.

The use case

Let’s say that you are creating a feature that displays information about an item that your app sells. This feature will download the item details from an endpoint on a server whenever the user selects an item from a list. Then you will get the item ID and make an HTTP request to this endpoint to retrieve the item details. But to be more efficient on data usage, you also should cache every item fetched, so if the user wants to see details of an item that was already cached, instead of fetching it from the endpoint, you’ll return the cached item.

To achieve this goal, this feature will have an ItemWorker class. It’s objective is to return an item, given an ID. This class will contain the mechanism to get the item from a cache through a CacheRepository or, request it to the endpoint using Network.

This is a possible implementation of this class:

Notice on this example that Network and CacheRepository are singletons, but however, I didn’t use their shared instance directly. I used a Dependency injection technique to make ItemWorker depend on protocols instead. So this way, when we test this class, we can create mocked-up classes that conform to NetworkProtocol and CacheRepositoryProtocol that give us full control to test any network scenario or cache state that we want. If you never heard of this concept, I highly recommend that you read this definition from Martin Fowler. Mastering dependency injection will take your testing abilities to a whole new level.

If you need a little bit more of context to understand my implementation of ItemWorker, you can see the definition of the NetworkProtocolCacheRepositoryProtocolItemRequest and Item bellow.

#testing #xcode #mobile-app-development #ios #swift

Testing asynchronous code in Swift
1.10 GEEK