erikdoe / ocmock

Mock objects for Objective-C
http://ocmock.org
Apache License 2.0
2.16k stars 606 forks source link

.andThrow(anException) will not throw the provided anException #538

Closed KaIKuxy closed 1 week ago

KaIKuxy commented 6 months ago

Based on the documentation:

OCMStub([mock someMethod]).andThrow(anException);

When someMethod is invoked the stub will throw anException.

However it seems like a special exception is thrown instead of the provided one, the provided one is wrapped inside the userInfo

https://github.com/erikdoe/ocmock/blob/4e8ba1624acf99378b163542d97abf299141c4bb/Source/OCMock/OCMExceptionReturnValueProvider.m#L20-L30


Repro

@interface Dummy : NSObject
- (void)method;
- (void)throwException;
@end

@implementation Dummy
- (void)method {
    @try {
        [self throwException];
    } @catch (NSException *exception) {
        NSLog(@"exception %@ %@", exception.name, exception.reason);
    }
}
- (void)throwException { }
@end

@interface DummyTests : XCTestCase
@end
@implementation DummyTests
- (void)testDummy {
    id dummyPartialMock = OCMPartialMock([Dummy new]);
    OCMStub([dummyPartialMock throwException]).andThrow([NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]);
    [dummyPartialMock method];
}
@end

The printed message will be exception OCMStubbedException Exception stubbed in test instead of exception name reason.

erikdoe commented 1 week ago

You're reading too much into what's printed. Yes, at some point that exception is thrown in the code you found, but that exception get's caught and unwrapped later: https://github.com/erikdoe/ocmock/blob/7f6e9e9b6c9ffa19a9040860da9f7a1f202b9f4d/Source/OCMock/OCMockObject.m#L388-L403

There's a unit test that shows the correct behaviour: https://github.com/erikdoe/ocmock/blob/7f6e9e9b6c9ffa19a9040860da9f7a1f202b9f4d/Source/OCMockTests/OCMockObjectMacroTests.m#L251-L258

In your dummy, please check what exception is actually thrown.