Unit testing private properties in Swift

Vinay Hosamane
3 min readDec 25, 2021

--

We all need to unit test our code before we ship that into the production environment. Almost every iOS developer writes unit tests for his/her code. I have written plenty of unit tests for mine as well as other codes in many projects.

While writing unit test cases, mostly we focus on testing the functionality. In the process, we may get some hurdles due to the usage of extensive abstraction or the usage of private properties in the code. Testing public properties or methods is pretty easy if you know how the object state behaves on changes. We can test the changes in public states but not the internal ones.

I recently came across an approach to access private properties from the test target without exposing them or elevating their access modifier.

Let’s take a simple use case here,

I have a class that creates a button and the content of the button is driven by a model.

Here button is private property, we don’t want the consumer to know about this. Where model will be public property, and the consumer can use this to inject his content.

It looks something like this.

SomeClass

If I am writing unit test cases for this piece of component, I may need to check the behavior inside the component when we apply the model. Basically here on the model set, we are setting the button title. So my test case should make sure to test the button text on model change.

How can we do that?
If you see the code, my button is not accessible outside this class. I somehow need to access this button inside the test target.

One way it could have been done is by elevating the access modifier of this button property to public or open. But that violates our design principle.

Alright, there is another way to do this. (bring the team into an agreement that it’s not misused)

Let’s write TestHooks to your component. Test hooks will expose the private properties you need from the test target. You can also add these test hooks under Debug macros.

It looks something like this.

TestHooks extension for SomeClass

Now you can easily test your private property state changes from test target like this.

XCTestCase class for SomeClass

I hope this helps you in your next unit test task.

Thank you for reading this article.

--

--