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

发布于 2024-12-07 14:08:42 字数 1314 浏览 13 评论 0原文

这个问题的观点很少,而且还没有答案。如果您有关于如何改变这个问题以吸引更多眼球的建议,我很乐意听到。干杯!

我正在使用< code>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

This question has very few views and no answers yet. If you have a suggestion what to change about this question to get more eyeballs, I'd be happy to hear them. Cheers!

I'm using GHAsyncTestCase to test a custom NSOperation of mine. I'm setting the test case as a delegate on the operation object and I'm calling didFinishAsyncOperation on the main thread when it's done.

When an assertion fails it throws an exception, which ought to be caught by the test case to render the test as "failed". But instead of this expected behavior, my app get's aborted by Xcode as soon as the assertion fails.

*** Terminating app due to uncaught exception 'GHTestFailureException', reason: ''NO' should be TRUE. This should trigger a failed test, but crashes my app instead.'

I'm obviously doing something wrong. Who can tell me?

@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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

染墨丶若流云 2024-12-14 14:08:42

我花了一个星期的时间来寻找解决方案,直到我终于休息了。对赏金问题几乎没有任何看法,而且没有人愿意尝试回答,这有点奇怪。我认为这个问题可能很愚蠢,但没有人投反对票,也没有人愿意纠正它。 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)];
}

I've been digging for a week to find a solution to this when I finally caught a break. It's been a bit weird having next to no views on a bounty question and no one cared to attempt an answer. I was thinking the question might be stupid, but there were no downvotes and no one cared to correct it either. Has StackOverflow become that saturated?

A solution.

The trick is to not assert anything from the callback method, but put the assertions back in the original test. The wait method is actually blocking the thread, which I didn't think of before. If your async callback receives any values, just store them in an ivar or property and then make assertions based on them in your original test method.

This takes care of the assertions not causing any crashes.

- (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)];
}
爱*していゐ 2024-12-14 14:08:42

查找你的 Xcode 断点导航器,删除所有异常断点,就这样!

Look up your Xcode Breakpoints navigator,delete all exception breakpoints,That's all !!!

辞慾 2024-12-14 14:08:42

查看 GHUnit 的头文件,看起来这可能是您的代码应该发生的情况。 GHUnit 的子类可以重写此方法:

// Override any exceptions; By default exceptions are raised, causing a test failure
- (void)failWithException:(NSException *)exception { }

不引发异常,但更简单的解决方案是使用 GHAssertTrueNoThrow 而不是 GHAssertTrue 宏。

Looking at the header files for GHUnit, it looks like that may be what is supposed to happen with your code. A subclass of GHUnit could override this method:

// Override any exceptions; By default exceptions are raised, causing a test failure
- (void)failWithException:(NSException *)exception { }

To not throw exceptions, but an easier solution is to use the GHAssertTrueNoThrow instead of GHAssertTrue macro.

巷子口的你 2024-12-14 14:08:42

我认为这个问题应该是“如何在 GHUnit 中使用块测试方法”?

答案可以在这里找到:http://samwize。 com/2012/11/25/create-async-test-with-ghunit/

I think this question should be rather, "how to test methods with blocks in GHUnit"?

And the answer can be found here: http://samwize.com/2012/11/25/create-async-test-with-ghunit/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文