在我的大多数使用默认值的类中,我使默认对象可设置为:
@property(retain) NSUserDefaults *defaults;
这应该会使测试变得更容易:
// In a nearby test class:
- (void) setUp {
[super setUp];
NSUserDefaults *isolatedDefaults = [[NSUserDefaults alloc] init];
[someObjectBeingTested setDefaults:isolatedDefaults];
}
但是现在我发现当我创建一个新的默认对象时,它已经有了一些值。那可能吗?我以为我可以通过调用-init
来创建一个空的,独立的默认对象。我是否在测试代码中的某处有错误,或者如果我想测试基于默认值的代码,我是否真的需要做一些更复杂的事情(如存根或模拟)?
答案 0 :(得分:8)
最后,我创建了一个简单的NSUserDefaults
替换,可用于控制测试中的默认环境。该代码可在GitHub上找到。
答案 1 :(得分:6)
来自NSUserDefaults文档:
init:返回使用当前用户帐户的默认值初始化的NSUserDefaults对象。
通常不应为空。我不确定你想在这里测试什么,因为测试NSUserDefaults功能会浪费时间。
但是说你需要一些键尚未注册,你的测试总是有相同的初始点:然后只需在setUp中删除它们(如果你愿意,可以在tearDown中恢复它们)。
类似的东西:
- (void) setUp {
[super setUp];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"myTestKey"];
// synchronize the change, or just use resetStandardUserDefaults:
[someObjectBeingTested setDefaults:[NSUserDefaults resetStandardUserDefaults]];
}
如果您没有特定的密钥列表但需要清除所有密钥,则必须使用CoreFoundation首选项实用程序,请参阅CFPreferencesCopyKeyList。
答案 2 :(得分:0)
我们还需要覆盖NSUserDefaults进行测试,但不想更改任何应用程序代码。
因此我们在NSUserDefaults
上编写了一个类别,允许我们在运行时使用方法调配覆盖objectForKey:
返回的值。
在Objective C中看起来像这样:
NSLog(@"Value before: %d", [[NSUserDefaults standardUserDefaults] boolForKey:@"Example"]);
// Value before: 0
[[NSUserDefaults standardUserDefaults] overrideValue:@(YES) forKey:@"Example"];
NSLog(@"Value after: %d", [[NSUserDefaults standardUserDefaults] boolForKey:@"Example"]);
// Value after: 1
在Swift中就像这样:
print(UserDefaults.standard.bool(forKey: "ExampleKey")) // false
UserDefaults.standard.overrideValue(true, forKey: "ExampleKey")
print(UserDefaults.standard.bool(forKey: "ExampleKey")) // true
您可以在Github上找到我们的代码:https://github.com/jakob/NSUserDefaultsOverride