C / ObjC:如何对单元进行单元测试?

时间:2013-06-09 18:39:44

标签: objective-c unit-testing block

根据此Stackoverflow帖子:Selectors or Blocks for callbacks in an Objective-C library

块似乎是ObjC的未来。然而,就像匿名函数一样,块感觉更像是“起草”一个实现。此外,由于其“嵌入式”性质,我担心过度使用它们会破坏单元测试或“可测试”OOP意义上的模块化。

我找不到关于如何测试块以及如何协调块和常规方法的测试的指南。这个话题有很好的资源吗?

3 个答案:

答案 0 :(得分:16)

我创建了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();
}

答案 1 :(得分:4)

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

https://github.com/allending/Kiwi

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

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

不确定那是不是你要找的东西。

答案 2 :(得分: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];
}