3

I'm testing an iOS application using KIF and OCMock, stubbing the device's ACAccountStore to return my own representation of a Twitter account. I want to stub requestAccessToAccountsWithType, and call the passed completion handler with my own values, but I can't seem to get the block from the invocation and call it properly (EXC_BAD_ACCESS). Being new to Objective-C and iOS, I'm sure I'm doing something wrong while pulling the block out of the NSInvocation.

This is the production code. The _accountStore is injected from the test setup.

ACAccountType *twitterType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[_accountStore requestAccessToAccountsWithType:twitterType withCompletionHandler:^(BOOL granted, NSError *error) {
    NSLog(@"authorized=%i in block", granted);
    // important code here
}];

Test setup code.

ACAccountStore *realStore = [[ACAccountStore alloc] init];
// Stub the store to return our stubbed Twitter Account
id mockStore = [OCMockObject partialMockForObject:realStore];
[[[mockStore stub] andDo:^(NSInvocation *invocation) {
    void (^grantBlock)(BOOL granted, NSError *error) = nil;
    [invocation getArgument:&grantBlock atIndex:1]; // EXC_BAD_ACCESS
    grantBlock(TRUE, nil); // run the important code with TRUE
}] requestAccessToAccountsWithType:[OCMArg any] withCompletionHandler:[OCMArg any]];
// not shown: inject the mockStore into production code
Jonathan Julian
  • 12,163
  • 2
  • 42
  • 48

1 Answers1

9

I think you should be using an index of 3, not 1. Index 0 is self, and index 1 is _cmd.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • Thanks! This is documented, I just missed it: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html – Jonathan Julian Nov 30 '11 at 00:44