How to Write Unit Tests for Selector Functions in Swift
In the Trendyol iOS project, we write unit tests for the codes in the presenter classes. We use Slather as a code coverage tool for our unit tests and based on its result we add unit tests for the uncovered code blocks. While writing unit tests, we realized that functions defined with the selector attributes cannot be tested like other functions. Before solving this problem, let’s take a look at how we define functions with selector attributes.
Selector Functions
In the example below, I tried to show the sample selector functions we use. We need to define the objc attribute at the beginning of the functions to use the selector attribute. Since these functions cannot be called from anywhere outside of the class, we limit their accessibility by adding the private attribute.
We define the functions that will work on the click action with the selector attribute as follows.
We wanted to write the unit tests for these functions, but the private attribute of the functions prevented us from accessing them directly. In order to solve this problem, we decided to trigger the function using the selector parameter in that I showed in the 1.2. picture.
While writing unit tests, we use a mock version of classes and we create these with SwiftMockGeneratorForXcode. In this way, we can easily check whether the logics in the presenter classes call the referenced classes successfully. I added the view class function’s mock version in the picture below.
In the unit tests, we triggered the function with selector parameter in the presenter classes and ensured that the selector function is assigned to the selector parameter of this function in the mock view. When we trigger this selector parameter, we will be able to test the selector function. In the picture 1.1., the dismissButtonTapped function calls the router class’s popupModule function with an animated parameter. We also created the mock version of the router to make it testable.
We accessed and triggered the selector functions in the unit tests as below.
By using the Thread.detachNewThreadSelector function, the selector function can be found. DetachNewThreadSelector as Apple documentation “detaches a new thread and uses the specified selector as the thread entry point”. In order to understand whether the function is working, we make the necessary controls asynchronously in the main queue.
In conclusion, we found a proper way to write unit tests for selector functions. Thank you for reading. If you have any questions, feel free to contact me.