为什么GHUnit中的异步测试中的错误断言会使应用程序崩溃而不是仅仅失败测试?

epo*_*gee 11 cocoa cocoa-touch unit-testing objective-c gh-unit

这个问题的观点很少,也没有答案.如果你有什么建议要改变这个问题以获得更多的眼球,我会很高兴听到它们.干杯!

我正在GHAsyncTestCase测试我的习惯NSOperation.我将测试用例设置为操作对象的委托,并在完成后调用didFinishAsyncOperation主线程.

当断言失败时,它会抛出一个异常,应该被测试用例捕获,以使测试"失败".但是,一旦断言失败,我的应用程序就会被Xcode中止,而不是这种预期的行为.

***由于未捕获的异常'GHTestFailureException'而终止应用程序,原因是:''NO'应该为TRUE.这应该会触发测试失败,但会导致我的应用崩溃.

我显然做错了什么.谁能告诉我?

@interface TestServiceAPI : GHAsyncTestCase
@end

@implementation TestServiceAPI

    - (BOOL)shouldRunOnMainThread
    {
        return YES;
    }

    - (void)testAsyncOperation
    {
        [self prepare];

        MyOperation *op = [[[MyOperation alloc] init] autorelease];

        op.delegate = self; // delegate method is called on the main thread.

        [self.operationQueue addOperation:op];

        [self waitForStatus:kGHUnitWaitStatusSuccess timeout:1.0];
    }

    - (void)didFinishAsyncOperation
    {
        GHAssertTrue(NO, @"This should trigger a failed test, but crashes my app instead.");

        [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testAsyncOperation)];
    }

@end
Run Code Online (Sandbox Code Playgroud)

epo*_*gee 12

当我终于休息一下时,我已经挖了一个星期才找到解决方案.在赏金问题上没有任何意见,并且没有人愿意尝试回答,这有点奇怪.我当时认为这个问题可能很愚蠢,但没有任何支持,也没有人愿意纠正它.StackOverflow会变得饱和吗?

一个办法.

诀窍是不要从回调方法中断言任何东西,而是将断言放回原始测试中.wait方法实际上阻塞了线程,我以前没有想到过.如果您的异步回调接收到任何值,只需将它们存储在ivar或属性中,然后在原始测试方法中根据它们进行断言.

这会处理不会导致崩溃的断言.

- (void)testAsyncOperation
{
    [self prepare];

    MyOperation *op = [[[MyOperation alloc] init] autorelease];

    op.delegate = self; // delegate method is called on the main thread.

    [self.operationQueue addOperation:op];

    // The `waitfForStatus:timeout` method will block this thread.
    [self waitForStatus:kGHUnitWaitStatusSuccess timeout:1.0];

    // And after the callback finishes, it continues here.
    GHAssertTrue(NO, @"This triggers a failed test without anything crashing.");
}

- (void)didFinishAsyncOperation
{
    [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testAsyncOperation)];
}
Run Code Online (Sandbox Code Playgroud)