1

我想为一个延迟调用另一个方法的方法编写黑盒单元测试。它看起来像这样:

- (void) doSomething {
    // Do something
    [self performSelector:@selector(doSomethingLater) withObject:nil afterDelay:kDelay];
}

- (void) doSomethingLater { }

wherekDelay是一个常数并且doSomethingLater是私有的。问题是kDelay1 秒,我不想减慢单元测试的执行速度。

doSomething在黑盒方法下(或尽可能多地)进行单元测试的最佳方法是什么?

唯一想到的是向类添加一个方法来更改 的值kDelay,但这可能会被其他开发人员意外使用。有没有侵入性较小的替代方案?

4

3 回答 3

0

我不知道它是否侵入性较小,但您可以-[NSObject performSelector:withObject:afterDelay:]使用您自己的不延迟版本来调整该方法。

Swizzling 意味着在运行时替换方法实现。免费查看JRSwizzle library

于 2011-12-11T22:38:22.143 回答
0

我要查看的第一件事是检测该方法是否已执行。正如@Rob 所说,我会考虑以不同的方法进行调酒。可能是测试的一个本地设置了一个布尔值以表明它已被调用。

下一个问题是减少延迟。由于 KDelay 是一个常数,因此您无法对它做任何事情。您可以将其更改为私有属性或您可以在测试和设置中访问的东西,但对于生产代码仍然是私有的。

另一种选择(我还没有研究过它是否可能!)不是太担心检测正在执行的方法,而是看看你是否可以检测到调用是运行循环堆栈,等待执行. 如果您可以检测到挂起呼叫的存在而不是呼叫本身,那么您可以立即执行此操作,并且延迟变得无关紧要。

于 2011-12-11T23:00:41.387 回答
0

您的测试是否要确保 doSomethingLater 已被调用并且它完成了它应该做的事情,而您所要做的只是缩短时间延迟?如果是这样,我建议您创建一个将常量值返回给 doSomething 的私有方法。就像是:

@implementation MyClass

- (NSUInteger) getDelay {
    return kDelay;
} 

@end

然后,您可以在运行时使用诸如 OCMock 其他测试框架之类的各种功能来存根 getDelay 的实现。

于 2011-12-11T23:02:58.373 回答