UserDefaults Unit testing in iOS

import Foundationprotocol UserDefaultKey {
var userDefaulKey: String {get set}
}
extension UserDefaults: UserDefaultKey {
var userDefaulKey: String {
get {
Keys.cartItemIDS
} set {
Keys.cartItemIDS = newValue
}
}
private enum Keys {
static var cartItemIDS = "cartItemIDs"
}
class var savedCartItems: [Int]? {
get {
return UserDefaults.standard.value(forKey: Keys.cartItemIDS) as? [Int]
} set {
UserDefaults.standard.set(newValue, forKey: Keys.cartItemIDS)
}
}
}
func manageProductInCart(product: MainProductModel) {
// get all saved product ids and store in an array
var availaleCartItemIDs = UserDefaults.savedCartItems ?? []
// if in case product is already available in cart, then dont add item in array. MainProductModel has a prperty id
guard availaleCartItemIDs.firstIndex(where: {$0 == product.id}) == nil else {
print("Item already available in cart. Retunr from here")
return
}
availaleCartItemIDs.append(product.id)
// save in user deafults. This will update the array of IDs saved in UserDefaults
UserDefaults.savedCartItems = availaleCartItemIDs
}
class UserDefaultsTest: XCTestCase {// Create a KEY for Unit test 
private var userDefaultTestKey = "userDefaultsTestKeyCart"
var cartViewModel: ProductViewModelProtocol!
override func setUp() {
UserDefaults.standard.userDefaulKey = userDefaultTestKey
let someFakeCartModel = ... Create a fake cart model
cartViewModel = CartListViewModel(model: someFakeCartModel)
}
override func tearDown(){
UserDefaults.standard.removeObject(forKey: userDefaultTestKey)
}
func testWhenItemRemovedFromCart() {
UserDefaults.savedCartItems = getFakeStoredCartProductIDs() // 1. Get some data from your fake
let beforeRemoving = UserDefaults.savedCartItems // 2. Store items in an array
let indexPath = IndexPath(row: 0, section: 0) // get an item from given indexpath. We are displying all products in UICollectionView.
let prouct = cartViewModel.product(at: indexPath) // Get a product from given indexpath from your ViewModel
cartViewModel.removeACartProduct(from: prouct) //3. Remove an item from cart
let afterRemoving = UserDefaults.savedCartItems
XCTAssertTrue(beforeRemoving?.count != afterRemoving?.count, "Could not remove item from cart") // 4
}
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store