Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test with NSUserDefaults?

In most of my classes that work with defaults I make the defaults object settable:

@property(retain) NSUserDefaults *defaults;

This is supposed to make testing easier:

// In a nearby test class:
- (void) setUp {
    [super setUp];
    NSUserDefaults *isolatedDefaults = [[NSUserDefaults alloc] init];
    [someObjectBeingTested setDefaults:isolatedDefaults];
}

But now I have found out then when I create a fresh defaults object, there are already some values in it. Is that possible? I thought I could create an empty, isolated defaults object by calling -init. Do I have a bug somewhere in the testing code, or do I really have to do something more complex (like stubbing or mocking) if I want to test my defaults-based code?

like image 440
zoul Avatar asked Oct 20 '10 13:10

zoul


People also ask

How do you check if NSUserDefaults is empty in Objective C?

There isn't a way to check whether an object within NSUserDefaults is empty or not. However, you can check whether a value for particular key is nil or not.

What is NSUserDefaults in Swift?

Overview. The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an app to customize its behavior to match a user's preferences. For example, you can allow users to specify their preferred units of measurement or media playback speed.

Is UserDefaults thread safe?

Thread SafetyThe UserDefaults class is thread-safe.

How do you save NSUserDefaults in Objective C?

Saving to NSUserDefaults : Basically, all you have to do is load NSUserDefaults, and then tell it to save a value to a specific key. Here is a simple example of writing an integer to NSUserDefaults: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];


2 Answers

In the end I have created a simple NSUserDefaults replacement that can be used to control the defaults environment in tests. The code is available on GitHub.

like image 70
zoul Avatar answered Sep 23 '22 13:09

zoul


From the NSUserDefaults documentation:

init: Returns an NSUserDefaults object initialized with the defaults for the current user account.

This should normally not be empty. I am not really sure what you want to test here, since it would be a waste of time to test NSUserDefaults functionality.

But say you need some keys to be not registered yet for your test to always have the same initial point: then just remove them in setUp (and restore them later in tearDown if you want to).

Something like:

- (void) setUp {
  [super setUp];

  [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"myTestKey"];

  // synchronize the change, or just use resetStandardUserDefaults:
  [someObjectBeingTested setDefaults:[NSUserDefaults resetStandardUserDefaults]];
}

If you don't have a specific list of keys but need to wipe out everything, you will have to use the CoreFoundation Preferences Utilities, see CFPreferencesCopyKeyList.

like image 42
w-m Avatar answered Sep 23 '22 13:09

w-m