Objective c 如何对EXC\u BAD\u访问进行单元测试?

Objective c 如何对EXC\u BAD\u访问进行单元测试?,objective-c,unit-testing,ocunit,Objective C,Unit Testing,Ocunit,我知道如何解决EXC_坏访问问题,但我不确定如何进行单元测试。有没有办法在代码中捕获EXC_BAD_访问,而不是简单地崩溃 这就是为什么我要问:我编写了一个大量使用块的库,如下所示: - (void)doSomething:(void (^)())myBlock; myBlock(); if (myBlock) { myBlock(); } 在我的doSomething:实现中,我将最终运行块,如下所示: - (void)doSomething:(void (^)())myBloc

我知道如何解决EXC_坏访问问题,但我不确定如何进行单元测试。有没有办法在代码中捕获EXC_BAD_访问,而不是简单地崩溃

这就是为什么我要问:我编写了一个大量使用块的库,如下所示:

- (void)doSomething:(void (^)())myBlock;
myBlock();
if (myBlock) {
    myBlock();
}
在我的
doSomething:
实现中,我将最终运行块,如下所示:

- (void)doSomething:(void (^)())myBlock;
myBlock();
if (myBlock) {
    myBlock();
}
如果调用者为该块传递nil,那么它将使用
EXC\u BAD\u ACCESS
崩溃,因此解决方案是检查该块是否存在,如下所示:

- (void)doSomething:(void (^)())myBlock;
myBlock();
if (myBlock) {
    myBlock();
}

这个nil检查很容易忘记,所以我想用一种方法编写一个在崩溃发生时失败的单元测试。我认为崩溃可以被视为测试失败,但我认为,对于试图运行测试的其他人来说,看到漂亮的失败消息比看到崩溃要好。有什么想法吗?

我建议使用

所以你可以这样做:

NSAssert(myBlock != nil, @"myBlock must not be nil")

这强制了在方法继续执行之前必须满足的先决条件。它还允许应用程序崩溃,并将为您提供除EXEC_BAD_ACCESS之外的其他原因。

我认为您需要在子流程中运行测试;然后,您可以让子流程崩溃,检查崩溃情况,如果发生,则测试失败

从…开始工作

然后,每个测试将在子流程中自行运行,如下所示:

- (void) testSomething {
    if (!isInSubprocess) {
            // Hand off this test's selector to be run in a subprocess
            [self runTestInSubprocess:_cmd];
            return;
    }

    // Put actual test code here
    STAssertEquals(1, 1, @"Something wrong with the universe.");

}

您可能需要对此进行调整;我还没有测试过它。

这对单元测试没有帮助;greenisus同样可以包含
if(myBlock){myBlock()}检查他在问题中提到的内容。除非我完全误解了,否则问题在于如何编写一个单元测试来捕获忘记检查被测代码中的块。Josh是对的。我可以很好地使用这个断言,但我真正想要测试的是,当我传递一个nil块时,我的方法不会崩溃,所以不管myBlock是否为nil。通过使用这个断言,您可以保证
myBlock
不是nil。如果您使用单元测试来测试该方法,那么测试将由于断言失败而失败。这不是我要问的。我希望nil是myBlock的一个可接受的值,所以我正在寻找一个测试,确保通过nil不会导致崩溃。明白了。我不知道,这很有趣。在第一次尝试中,无论我做什么,它最终都无法通过测试,但该项目的目标是作为一个Cocoa Touch静态库,运行测试将启动iPhone模拟器。我认为fork()在那里不起作用,所以我也要把它作为Mac/Cocoa的目标来尝试,看看会发生什么。谢谢哦,是的,我不知道iOS上是否有
fork()
,对不起。我也很难让它完全正常工作;如果我发现了什么,我会更新。@greenisus你有机会在iOS上成功地解决这个问题吗?我也在寻找一种在崩溃发生时让测试失败的方法,特别是在Swift中。