在我的一个方法中,我使用的是dispatch_once,我为其创建了一个静态变量。该方法按预期工作,单独运行时单元测试成功通过。但是当我同时运行测试时,其中一个测试失败了,因为方法中的静态变量保持了值。
我的方法:
+ (NSString *)myMethod
{
static NSString *dayOfTheWeek;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Do something.
dayOfTheWeek = @"Monday";
if (!dayOfTheWeek)
{
dayOfTheWeek = @"Sunday";
}
});
return dayOfTheWeek;
}
问题:
所以我有单元测试来测试"星期一"和另一个测试"星期日"的单元测试。如果我在XCODE上单独执行这两个测试,它们会通过,但是当我一起执行它们时,测试"星期日"失败,因为我的静态变量仍然保持值"星期一"。
有没有办法可以清除方法级静态变量仅用于测试目的?或者还有其他方法可以成功执行这两项测试吗?
答案 0 :(得分:5)
条件逻辑几乎从不属于dispatch_once()
块。如果某种逻辑在不同的执行中可能有所不同,那么每次执行程序时可能需要更频繁地重新评估一次。目前还不清楚逻辑是什么,但是如果它类似于什么?今天是什么?"那么,如果你的程序运行了多天会发生什么?
答案 1 :(得分:1)
问题在于您错误地设计了此方法。两个考虑因素:
(1)一旦意味着一次。你不能签一份半合同。此代码将在应用程序的整个生命周期内执行一次。无论你改变输入,是否创建这个类的新实例等等,你调用它的次数并不重要。
(2)您要做的是研究 memoization 的概念。这是当您将输入与输出匹配时进行耗时的计算。一个好的模型是一个可变的字典。当输入到达时,您将在字典中查找该输入。如果结果在那里,则返回;如果它不存在,执行计算,将结果放在那里,然后返回。这样,您就可以避免为每个可能的输入进行耗时的计算。
答案 2 :(得分:0)
我认为myMethod
需要重构可测试性。如下所示:
// NOT THREAD-SAFE
static NSString *dayOfTheWeek;
+ (void) myMethodSetValue(NSString* value)
{
dayOfTheWeek = value;
}
+ (NSString*) myMethodGetValue()
{
return dayOfTheWeek;
}
+ (NSString *)myMethod
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
myMethodSetValue(&dayOfTheWeek, @"Monday");
});
return myMethodGetValue();
}
测试1
myMethodSetValue(@"Monday");
...
test routine
的Test2
myMethodSetValue(@"Sunday");
...
test routine