2010-10-20 11 views
16

In den meisten meiner Klassen, die mit Ausfällen arbeiten mache ich die Standardwerte Objekt einstellbar:Wie mit NSUserDefaults testen?

@property(retain) NSUserDefaults *defaults; 

Diese Prüfung machen soll einfacher:

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

Aber jetzt fand ich heraus dann, wenn ich erstellen ein neues Standard-Objekt, da sind schon einige Werte drin. Ist das möglich? Ich dachte, ich könnte ein leeres, isoliertes Standardobjekt erstellen, indem ich -init aufrufen. Habe ich irgendwo im Testcode einen Fehler oder muss ich wirklich etwas Komplexeres machen (wie Stubbing oder Mocking), wenn ich meinen Standard-basierten Code testen möchte?

Antwort

8

Am Ende habe ich eine einfache NSUserDefaults Ersetzung erstellt, die verwendet werden kann, um die Standardumgebung in Tests zu steuern. Der Code ist unter GitHub verfügbar.

+0

Danke für die Erstellung! – Palimondo

+0

sehr schön, danke! Ich benutze jetzt Ihre Klasse, aber anstatt 'NSUserDefaults' als Parameter zu' someObjectBeingTested' zu injizieren, verwende ich 'Kiwi' mit seiner spöttischen Fähigkeit zu stub. Verwenden Sie etwas wie: 'id transientDefaults = [NSUserDefaults transientDefaults]; [NSUserDefaults stub: @selector (standardUserDefaults) undReturn: transientDefaults]; ' – kernix

6

Von der NSUserDefaults Dokumentation:

init: Gibt ein NSUserDefaults Objekt mit den Standardeinstellungen für das aktuelle Benutzerkonto initialisiert.

Dies sollte normalerweise nicht leer sein. Ich bin mir nicht sicher, was Sie hier testen wollen, da es Zeitverschwendung wäre, die NSUserDefaults-Funktionalität zu testen.

Aber sagen Sie, dass Sie einige Schlüssel brauchen, um noch nicht registriert zu sein, damit Ihr Test immer den gleichen Anfangspunkt hat: dann entfernen Sie sie einfach in setup (und stellen Sie sie später in tearDown wieder her).

Etwas wie:

- (void) setUp { 
    [super setUp]; 

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

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

Wenn Sie aber alles wischen müssen nicht eine bestimmte Liste von Tasten aus, müssen Sie die Einstellungen Corefoundation Dienstprogramme verwenden, finden Sie CFPreferencesCopyKeyList.

+0

Ich möchte Code testen, der Benutzerstandards für einige Eingabe und Ausgabe verwendet. Wenn ich "echte" Benutzereinstellungen verwende, hätte ich Schwierigkeiten, die Umgebung zu kontrollieren - ich müsste unerwünschte Werte löschen, andere nach dem Ausführen der Tests wiederherstellen und so weiter. Am Ende habe ich eine Art Standardersatz für Testzwecke geschrieben, siehe meine Antwort. Vielen Dank! – zoul

+0

Aus irgendeinem Grund funktionierte das Setzen eines BOOL-Schlüssels auf NO nicht, aber die Verwendung von removeObjectForKey funktionierte perfekt. Also danke für den Tipp. – phatmann