Может ли OCMock запустить параметр блока?

Предположим, что подпись метода:

- (void)theMethod:(void(^)(BOOL completed))completionBlock; 

Я хотел бы высмеять эту подпись метода, чтобы гарантировать, что метод вызывается, и просто вызвать блок завершения. Я вижу из других сообщений, подобных этому, что я могу высмеять вызов метода и принять любой блок, но не запустить блок. Я также знаю, что есть метод andDo, который я мог бы использовать, но я не могу понять, как передать блок и запустить его.

Есть идеи?

Благодарю.

5 Solutions collect form web for “Может ли OCMock запустить параметр блока?”

Вы можете использовать [[mock stub] andDo:] как это, чтобы передать другой блок, который вызывается, когда вызывается ваш издеваемый метод:

 void (^proxyBlock)(NSInvocation *) = ^(NSInvocation *invocation) { void (^passedBlock)( BOOL ); [invocation getArgument: &passedBlock atIndex: 2]; }; [[[mock stub] andDo: proxyBlock] theMethod:[OCMArg any]]; 

Блок получает экземпляр NSInvocation из которого вы можете запросить все используемые аргументы. Обратите внимание, что первый аргумент находится в индексе 2, так как у вас есть self и _cmd по индексам 0 и 1.

EDIT 2: Вместо этого используйте https://stackoverflow.com/a/32945785/637641 .

Использование andDo: отлично, но лично я предпочитаю [OCMArg checkWithBlock:] .

 [[mock expect] theMethod:[OCMArg checkWithBlock:^BOOL(id param) { void (^passedBlock)( BOOL ) = param; // Normally I set some expectations here and then call the block. return YES; }]]; // Code to test [mock verify]; 

Вы также можете использовать [mock stub], но я предпочитаю проверять, что вызывается метод.

ИЗМЕНИТЬ 1

Версия OCMock 3:

 OCMExpect([mock theMethod:[OCMArg checkWithBlock:^BOOL(void (^passedBlock)(BOOL)) { // call the block... return YES; }]]); // Code to test OCMVerify(mock); 

Это теперь поддерживается в OCMock 3.2. Вы можете использовать [OCMArg invokeBlock] и [OCMArg invokeBlockWithArgs:...] чтобы вызвать блок, переданный в качестве аргумента в закодированный метод.

Иногда требуется использовать andDo: блоки, но для большинства случаев вы можете использовать [OCMArg invokeBlock] или [OCMArg invokeBlockWithArgs:] .

В вашем примере вы можете сделать следующее
Если вас не волнуют аргументы:

 // Call block with default arguments. OCMStub([mock theMethod:[OCMArg invokeBlock]]; 

Если вы хотите отправить конкретные аргументы:

 // Call block with YES. OCMStub([mock theMethod:([OCMArg invokeBlockWithArgs:@YES, nil])]; 

Обратите внимание на завершение nil поскольку вы можете передать несколько аргументов этому методу. Кроме того, все выражение должно быть заключено в круглые скобки.

Подробнее об этом можно узнать в документации OCMock .

Это ответ Свена, обновленный для OCMock 3.

 OCMStub([myMock myMethodWithMyBlock:[OCMArg any]]).andDo(^(NSInvocation *invocation) { void (^passedBlock)(BOOL myFirstArgument, NSError *mySecondArgument); [invocation getArgument: &passedBlock atIndex: 2]; passedBlock(YES, nil); }); 
  • XCTestExpectation - вызов метода async дважды приводит к нарушению API
  • stub init] не работает, но принятый ответ говорит, что он должен работать
  • Как динамически изменить цель для модульных тестов в Xcode 7?
  • Настраивать индивидуальные тестовые примеры XCTest в Xcode 5 на конкретное устройство iOS для универсального приложения?
  • Как изменить словарь приложения NSProcessInfo приложения из модульного теста?
  • Как я могу тестировать контроллеры представлений iOS?
  • Сравнение классов, isKindOfClass не работает в спецификации Kiwi
  • Условное модульное тестирование на основе версии iOS
  • Ошибка выполнения модульных тестов Cedar из командной строки
  • Xcode 5 xcodebuild unit test, похоже, возвращает статус успешно при неудачных тестах
  • Не удается передать делегата приложения делегату приложения в тестах
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.