假设方法签名如下:
- (void)theMethod:(void(^)(BOOL completed))completionBlock;
我想模拟此方法签名以确保调用该方法,并只调用完成块。我从this one等其他帖子中看到,我可以模拟方法调用并接受任何块,但不能运行块。我也知道有一种我可以使用的doDo方法,但我无法弄清楚如何传递一个块并运行它。
有什么想法吗?
感谢。
答案 0 :(得分:32)
您可以像这样使用[[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,因为索引0和1处有self和_cmd。
答案 1 :(得分:17)
编辑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]但我更愿意验证调用theMethod。
编辑1
OCMock 3版本:
OCMExpect([mock theMethod:[OCMArg checkWithBlock:^BOOL(void (^passedBlock)(BOOL))
{
// call the block...
return YES;
}]]);
// Code to test
OCMVerify(mock);
答案 2 :(得分:11)
现在OCMock 3.2支持此功能。您可以使用[OCMArg invokeBlock]
和[OCMArg invokeBlockWithArgs:...]
来调用作为存根方法的参数传递的块。
答案 3 :(得分:7)
有时需要使用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 documentation中了解更多相关信息。
答案 4 :(得分:2)
这是针对OCMock 3更新的Sven的答案。
OCMStub([myMock myMethodWithMyBlock:[OCMArg any]]).andDo(^(NSInvocation *invocation) {
void (^passedBlock)(BOOL myFirstArgument, NSError *mySecondArgument);
[invocation getArgument: &passedBlock atIndex: 2];
passedBlock(YES, nil);
});