Obj-C: как получить и вызвать аргумент блока из NSInvocation - заглушка учетной записи Twitter на iOS - PullRequest
3 голосов
/ 30 ноября 2011

Я тестирую приложение для iOS, используя KIF и OCMock, заглушая ACAccountStore устройства, чтобы вернуть мое собственное представление учетной записи Twitter. Я хочу заглушить requestAccessToAccountsWithType и вызвать обработчик прошедшего завершения со своими собственными значениями, но я не могу получить блок из вызова и правильно его вызвать (EXC_BAD_ACCESS). Будучи новичком в Objective-C и iOS, я уверен, что делаю что-то не так, вытаскивая блок из NSInvocation.

Это рабочий код. _accountStore вводится из настройки теста.

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

Код настройки теста.

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

1 Ответ

9 голосов
/ 30 ноября 2011

Я думаю, вы должны использовать индекс 3, а не 1. Индекс 0 равен self, а индекс 1 равен _cmd.

...