如何在单元测试中捕获NSBlockOperation中的异常?

时间:2017-06-16 16:30:21

标签: ios objective-c unit-testing exception nsoperation

我正在尝试创建NSBlockOperation的子类,以便在抛出任何内容时使用备用执行块捕获异常。但是,在单元测试中,Xcode不会让我通过导致崩溃的执行块,尽管在子类或单元测试中包含在try / block中。有什么想法吗?

似乎这个问题特定于NSOperation上下文中抛出的异常,因为我可以使用try / catch在执行块之外添加相同的代码,而不会导致测试中止。以下是相关代码:

子类:

// ABCTryBlockOperation.h

typedef void(^ExecutionBlock)(void);

@interface ABCTryBlockOperation : NSBlockOperation

@property (copy) ExecutionBlock catchBlock;

@end


// ABCTryBlockOperation.m

#import "ABCTryBlockOperation.h"

@implementation ABCTryBlockOperation

- (void)main {
    @try {
        [super main];
    } @catch (NSException *exception) {
        NSLog(@"Catching exception in operation named '%@'", self.name ?: @"Unknown");
        if (self.catchBlock) {
            self.catchBlock();
        }
    }
}

@end

单元测试:

#import <XCTest/XCTest.h>
#import "ABCTryBlockOperation.h"
#define EXP_SHORTHAND
@import Expecta;

@interface ABCTryBlockOperationTests : XCTestCase

@end

@implementation ABCTryBlockOperationTests

- (void)testFailingExecutionBlocks {
    __block NSUInteger result = -1;
    @try {
        NSNumber *number = nil;
        NSArray *array = @[number];
        result = [[array firstObject] integerValue];
    } @catch (NSException *exception) {

    } @finally {

    }
    ABCTryBlockOperation *operation = [ABCTryBlockOperation new];
    [operation addExecutionBlock:^{
        result = 3 * 5;
    }];
    [operation addExecutionBlock:^{
        NSNumber *number = nil;
        // ======================== < Tests will not pass this line \/
        NSArray *array = @[number];
        // ========================
        result = [[array firstObject] integerValue];
    }];
    [operation setCatchBlock:^{
        result = 1;
    }];

    [operation start];
    [operation waitUntilFinished];

    expect(result).to.equal(1);
}

- (void)testSuccessfulExecutionBlocks {
    __block NSUInteger result = -1;
    ABCTryBlockOperation *operation = [ABCTryBlockOperation new];
    [operation addExecutionBlock:^{
        result = 3 * 5;
    }];
    [operation addExecutionBlock:^{
        result = 3 * 8;
    }];
    [operation setCatchBlock:^{
        result = 1;
    }];
    [operation start];
    [operation waitUntilFinished];

    expect(result).to.equal(24);
}

@end

0 个答案:

没有答案