2

I have a unit test that tests if method throws an exception when condition is present, and method does throws exception as expected.

- (void)testMethodThrowsWhenConditionIsPresent {
    XCTAssertThrows([Foo methodWithCondition: condition], @"Condition is true, method should throw exception");
}

Here is the exception source:

- (void)methodWithCondition:(someType)condition {
    if (condition) {
        [NSException raise: @"condition is true!" format: @"condition is true!"];
    }
}

Why does the test stop at the line the exception is thrown? The test does not go on, it stops at that line, when I expect it to continue and return 1 from XCTAssertThrows(), making the test succeed. The test instead stops with Xcode bringing me to the line it was thrown, with a green `Thread 1: breakpoint 1.1' and the debugger appearing in the console.

Eliza Wilson
  • 1,031
  • 1
  • 13
  • 38
  • 1
    Why do you mean by "stop"? Do you hit a breakpoint in the debugger? Does the app terminate? How do you know it stopped on that line? – Jonah Mar 13 '14 at 16:21
  • @Jonah I clarified it in the edit. – Eliza Wilson Mar 13 '14 at 16:24
  • So, do you have an exception breakpoint set? – Hot Licks Mar 13 '14 at 16:25
  • @HotLicks Yes, on my whole project. I see that is the problem now... Is there a way to selectively disable it for tests? – Eliza Wilson Mar 13 '14 at 16:28
  • 1
    You could just delete the breakpoint. It's easy enough to turn on again. Or click on it once to disable it, and toggle the breakpoint with another click. – Abizern Mar 13 '14 at 16:38
  • @Abizern When I disable/delete the breakpoint, now it just doesn't stop at the line in the code editor and gives more information on the crash in the console. – Eliza Wilson Mar 13 '14 at 23:56
  • Does this answer your question? [XCTAssertThrows stops at breakpoint](https://stackoverflow.com/questions/22020527/xctassertthrows-stops-at-breakpoint) – Senseful Nov 07 '20 at 19:32

1 Answers1

4

Why does the test stop when the execution is thrown?

Because you have a breakpoint, which stops execution.

Why, after removing the breakpoint, does my application crash when the exception is thrown?

Because you have an unhandled exception. Unhandled exceptions cause your program to crash.

How can I handle an exception so it won't crash my program?

The easy answer to this question is to simply NOT throw an exception. In other programming languages, like Java, this is perfectly standard. But in Objective-C, we don't really do exceptions. In Objective-C, exceptions should be saved for TRULY exceptional behavior.

With that said, and a strong suggestion for you to find another way to handle whatever it is you're trying to handle, this is how you handle an exception in Objective-C:

@try {
    // code that could throw an exception
}

@catch (NSException *e) {
    // handle the exception...
}

@finally {
    // post try-catch code, executed every time
}
shim
  • 9,289
  • 12
  • 69
  • 108
nhgrif
  • 61,578
  • 25
  • 134
  • 173
  • 1
    Your answer was very useful but I have to say I disagree with the part "The easy answer to this question is to simply NOT throw an exception". If that were true, they should remove support for XCTAssertThrows. Maybe they should (you're throwing an unexpected exception that you're ...expecting) remove it by virtue of an exception's definition for objective-c, but it would be nice if they could disable that exception while this test is running (xCode knows all this, it's running the test!). I might agree that if you don't want to see this, disable the debugger. That's what it does for a living. – Pierre-Francoys Brousseau Aug 28 '14 at 23:42
  • Simply having breakpoints enabled when testing stops when throwing code is called. I don't know why but i had to google it twice in a matter of few weeks because i thought the tests crashed. – Cristi Băluță Mar 03 '17 at 09:27