Objective-C中的延迟单元测试方法

Objective-C中的延迟单元测试方法,objective-c,unit-testing,black-box-testing,Objective C,Unit Testing,Black Box Testing,我想为一个方法编写黑盒单元测试,该方法调用另一个具有延迟的方法。有点像这样: - (void) doSomething { // Do something [self performSelector:@selector(doSomethingLater) withObject:nil afterDelay:kDelay]; } - (void) doSomethingLater { } 其中,kDelay是一个常量,doSomethingLater是私有的。问题是kDelay

我想为一个方法编写黑盒单元测试,该方法调用另一个具有延迟的方法。有点像这样:

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

- (void) doSomethingLater { }
其中,
kDelay
是一个常量,
doSomethingLater
是私有的。问题是
kDelay
只有1秒,我不想减慢单元测试的执行速度

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


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

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


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

我要看的第一件事是检测该方法是否已执行。所以正如@Rob所说,我会用另一种方法来研究swizzling。可能有一个本地测试设置了bool来表示它被调用了

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


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

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

@implementation MyClass

- (NSUInteger) getDelay {
    return kDelay;
} 

@end

然后,您可以在运行时使用OCMock等测试框架的各种功能来取消getDelay的实现。

我想我会说它以另一种方式具有侵入性。这种方法的问题是,如果出于某种原因,有人决定将performSelector更改为另一种延迟方法,那么测试将变得缓慢没有人会知道为什么。不过,如果能够快速切换常量就好了。您可以将常量更改为返回常量值的方法,然后快速切换该方法。