Test iOS code that relies on a shared instance
Learn how to test iOS that relies on shared instance
As an experienced iOS developer, a question you may encounter during an interview could be:
“What is your approach to testing this view model that directly references the user default shared instance?”
While you may answer something like below, you will see that this solution has its problems.
Problem
The issue at hand is that the view model has a strong dependency on the user default shared instance, which makes it challenging to conduct isolated testing. Presently, tests must be aware of user defaults and must reset its values before each test to prevent inaccurate results. Furthermore, this test is considered an integration test rather than a unit test.
Solution :
The objective is to store the username without the requirement of manipulating user defaults. To accomplish this, a new component is introduced that specifically manages user default mechanisms for user data, instead of calling the singleton within the view model.
Another issue resolved by this solution is the need for the caller of the view model (such as a view controller) to be aware of and manage keys for user default key values which is not its responsibility. With the introduction of the UserStorageWithUserDefaults component, this responsibility is shifted entirely to the component.
The view model can now use this new UserStorage component :
As demonstrated, the UserStorage component is now injected into the view model. Therefore, we must modify the code that calls the ViewModel, as follows. From :
To this version :
Finally, for test code, we can leverage a dedicated implementation of the UserStorage protocol that exists solely in memory and does not depend on any external framework: