繁体   English   中英

在Objective-C中对方法进行延迟的单元测试

[英]Unit testing a method with delay in Objective-C

我想编写一种黑盒单元测试,该方法可以延迟调用另一个方法。 看起来像这样:

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

- (void) doSomethingLater { }

其中kDelay是常数,而doSomethingLater是私有的。 问题是kDelay是1秒,我不想减慢单元测试的执行速度。

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

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

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

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

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

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

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

您的测试是否要确保已调用doSomethingLater并确保它已执行预期的操作,而您要做的就是缩短时间延迟? 如果是这样,我建议您创建一个私有方法,该方法将常量值返回给doSomething。 就像是:

@implementation MyClass

- (NSUInteger) getDelay {
    return kDelay;
} 

@end

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM