OCMock可以运行块参数吗?
假设一个方法签名,如下所示:
- (void)theMethod:(void(^)(BOOL completed))completionBlock;
我想嘲笑这个方法签名,以确保该方法被调用,只是调用完成块。 我从其他职位看到这样的一个 ,我可以嘲笑方法调用,并接受任何块,但不运行该块。 我也知道有一个andDo方法可以使用,但我不知道如何传递一个块并运行它。
有任何想法吗?
谢谢。
你可以像这样使用[[mock stub] andDo:]
来传递另一个在调用[[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。
编辑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];
你也可以使用[模拟存根],但我更喜欢validation方法被调用。
编辑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:...]
来调用作为parameter passing给存根方法的块。
使用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])];
请注意,因为您可以将多个parameter passing给此方法,所以nil
终止。 另外,整个expression式必须用括号括起来。
您可以在OCMock文档中阅读更多关于它的信息 。
这是Sven为OCMock 3更新的答案。
OCMStub([myMock myMethodWithMyBlock:[OCMArg any]]).andDo(^(NSInvocation *invocation) { void (^passedBlock)(BOOL myFirstArgument, NSError *mySecondArgument); [invocation getArgument: &passedBlock atIndex: 2]; passedBlock(YES, nil); });