So I have a class I'm trying to unit test that uses both UserDefaults and NSUbiquitousKeyValueStore. I can easily mock UserDefaults using UserDefaults(suiteName: #file) (for example), but I can't figure out how to mock NSUbiquitousKeyValueStore. I can't seem to find any thread about it here on SO, and my google-fu is lacking.
Here's the beginning of my test class just for reference:
class ReviewTests: XCTestCase {
private var userDefaults: UserDefaults = UserDefaults(suiteName: #file)!
private var ubiquitousKeyValueStore: NSUbiquitousKeyValueStore = // How do I mock this?
private var reviewPromptController: ReviewPromptController!
What I did to unit test my interactions with
NSUbiquitousKeyValueStorewas to create a protocol that my custom cloud-storage wrapper aroundNSUbiquitousKeyValueStoreandNSUbiquitousKeyValueStoreconform to. Those implementations are below:KeyValueStoreis a protocol, which contains method signatures thatNSUbiquitousKeyValueStorehas. By doing so, I can create a type that can be used in tests where an instance ofNSUbiquitousKeyValueStorecould be used.Next, I conformed
NSUbiquitousKeyValueStoretoKeyValueStore. Nothing else needed to be done forNSUbiquitousKeyValueStoresince it already implements the methods defined inKeyValueStore.Then, I created a type that is a wrapper around
NSUbiquitousKeyValueStore.UserSettingsStorageaccepts any type that conforms toKeyValueStore. SinceNSUbiquitousKeyValueStoreandMockCloudKeyValueStoreboth conform toKeyValueStore, I can pass an instance ofNSUbiquitousKeyValueStorein production and an instance ofMockCloudKeyValueStorein tests.Finally, I can use my mock in my unit tests, ensure that
NSUbiquiousKeyValueStore.didChangeExternallyNotificationis called from my mock, and then verify that my wrapper aroundNSUbiquitousKeyValueStoreresponds as expected to the notification.