1

According to this Stackoverflow post: Selectors or Blocks for callbacks in an Objective-C library ,

blocks seem to be the future of ObjC. However, much like anonymous functions, blocks feel more like "drafting" an implementation. Also, due to its "embedded" nature, I fear that overusing them will break modularity in the sense of unit-testing or "testable" OOP.

I couldn't find much guideline on how to test blocks and how to coordinate tests for blocks and regular methods. Are there good resources for this topic?

4

3 回答 3

17

我创建了 3 个宏等待块在单元测试中执行,因此可以在块内进行断言。

#define TestNeedsToWaitForBlock() __block BOOL blockFinished = NO
#define BlockFinished() blockFinished = YES
#define WaitForBlock() while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !blockFinished)

例子:

- (void)testWaitForBlock {
    TestNeedsToWaitForBlock();

    [target selectorWithInlineBlock:^(id obj) {

        // assertions

        BlockFinished();
    }];

    WaitForBlock();
}
于 2013-08-21T13:28:45.437 回答
4

不确定您是否已经尝试过,但我使用 Kiwi 对我的 iOS 应用程序进行单元测试。它没有令人惊讶的记录,但它可以用于测试块。

https://github.com/allending/Kiwi

看看他们 wiki 上“模拟和存根”下的“捕获参数”。您可以使用它来捕获正在传递的块。这对于异步代码非常有用 - 您可以调用要测试的方法,捕获一些完成块,然后立即同步执行该块,从而使您的异步代码有效地同步。

关于块感觉就像起草一个实现 - 他们不必那样。我将块定义为一种方法,而不是内联。事实上,我经常编写一个返回块的方法,使代码干净且易于测试。

不知道这是否是你要找的。

于 2013-06-09T18:55:55.443 回答
0
- (void)testWaitForBlock {
    [target selectorWithInlineBlock:^(id obj) {

        // assertions

        BlockFinished();
    }];
   //use this to keep runloop is alive ,you can do anything.
   NSDate * date = [NSDate dateWithTimeIntervalSinceNow:10];
    [[NSRunLoop currentRunLoop]runUntilDate:date];
}
于 2016-06-29T02:33:02.750 回答