How to access UIViewController delegate methods in SenTestCase implementation with blocks?

408 Views Asked by At

I am writing some automated tests that will test some actions happening inside my root UIViewController. As of now I'm using SenTestCase. I am using storyboards also. How can I do this? And how can I easily listen for delegate methods on the view controller's UIWebView?

What I've tried is to store a block which runs after web view is completed loading its content.

@interface FirstViewController : UIViewController
typedef void (^webViewDoneLoadingBlock)(void);
@property (nonatomic,strong) webViewDoneLoadingBlock doneLoading;
@end

I run this block in First view controller's UIWebView's delegate method:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.doneLoading();
}

In setUp I fetch out the first view controller from the storyboard:

- (void)setUp
{
    [super setUp];
    UIStoryboard *storyboard = 
      [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
    UINavigationController *navController = [storyboard instantiateInitialViewController];
    FirstViewController *firstVC = (id) navController.topViewController;
    self.firstViewController = firstVC;

}

The test (I use dispatchSemaphoreInBlock: to get the test to wait till thenResume is called to say if the test failed or not):

- (void)testExample
{

    [self dispatchSemaphoreInBlock:^(void (^thenResume)(void)) {

        self.firstViewController.doneLoading = ^{
            NSLog(@"done LOADING");
            thenResume();
        };
    }];
}

What fails is EXC_BAD_ACCESS when hitting self.doneLoading(); in webViewDidFinishLoad:

Am I storing the block wrong here? Or is there another way to hang on to the FirstViewController's delegate methods from the SenTestCase class?

Code for the dispatch semaphore (this is code I've used through many other projects, so I know this isn't the reason why it fails):

- (void)dispatchSemaphoreInBlock:(void (^)(void (^resume)(void)))theBlock
{
    dispatch_semaphore_t theSemaphore = dispatch_semaphore_create(0);
    theBlock(^{
        dispatch_semaphore_signal(theSemaphore);
    });

    while ( dispatch_semaphore_wait(theSemaphore, DISPATCH_TIME_NOW) ) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                                 beforeDate:[NSDate distantFuture]];
    }
}
0

There are 0 best solutions below