Created
March 2, 2020 01:37
-
-
Save CassiusPacheco/bf3fdc9e27b189d9b2c858caa65a3b67 to your computer and use it in GitHub Desktop.
Testable @userdefaults property wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public protocol UserDefaultsInterface { | |
func set(_ value: Any?, forKey defaultName: String) | |
func object(forKey defaultName: String) -> Any? | |
} | |
extension UserDefaults: UserDefaultsInterface {} | |
class UserDefaultsMock: UserDefaultsInterface { | |
var valueSet: Any? | |
var valueSetKey: String? | |
var objectKey: String? | |
var objectToBeReturned: Any? | |
func set(_ value: Any?, forKey defaultName: String) { | |
valueSet = value | |
valueSetKey = defaultName | |
} | |
func object(forKey defaultName: String) -> Any? { | |
objectKey = defaultName | |
return objectToBeReturned | |
} | |
} | |
enum UserDefaultsKeys: String { | |
case userSeenPopUp = "user_seen_popup" | |
} | |
@propertyWrapper | |
struct Preferences<T> { | |
var defaults: UserDefaultsInterface = UserDefaults.standard | |
let key: UserDefaultsKeys | |
let defaultValue: T | |
var wrappedValue: T { | |
get { | |
defaults.object(forKey: key.rawValue) as? T ?? defaultValue | |
} set { | |
defaults.set(newValue, forKey: key.rawValue) | |
} | |
} | |
init(wrappedValue: T, key: UserDefaultsKeys) { | |
defaultValue = wrappedValue | |
self.key = key | |
} | |
} | |
class SomeClass { | |
@Preferences(key: .userSeenPopUp) | |
var hasUserSeenPopUp = false | |
init(defaults: UserDefaultsInterface = UserDefaults.standard) { | |
_hasUserSeenPopUp.defaults = defaults | |
} | |
func showPopUpIfNecessary() { | |
guard !hasUserSeenPopUp else { return } | |
// show pop up | |
hasUserSeenPopUp.toggle() | |
} | |
} | |
let mock = UserDefaultsMock() | |
let test = SomeClass(defaults: mock) // Inject mocked instance into the property wrapper | |
assert(!test.hasUserSeenPopUp) | |
test.showPopUpIfNecessary() | |
assert(mock.valueSet as? Bool == true) | |
assert(mock.valueSetKey == UserDefaultsKeys.userSeenPopUp.rawValue) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment