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); });