[OCMock][OCMProtocolMock][OCMStub]当我OCMProtocolMock一个协议(这个协议有一个方法)时,我如何调用这个方法的真正实现

[OCMock][OCMProtocolMock][OCMStub]When I OCMProtocolMock a protocol(This protocol has a method),How can I invoke the real implementation of the method

代码如下:

- (void)test_method {
    id mockDelegate = OCMProtocolMock(@protocol(adDelegate));
    OCMExpect([mockDelegate adLoaded:OCMOCK_ANY error:OCMOCK_ANY]);
    self.delegate = mockDelegate;
    if ([self.delegate respondsToSelector:@selector(adLoaded:error:)]) {
         [self.delegate adLoaded:array error:nil];
    }
    OCMVerifyAllWithDelay(mockDelegate, 15);
}

// adDelegate callback method
- (void)adLoaded:array:(NSArray*)array error:(NSError *)error {
    ......
    ......
}

因为我让:self.delegate = mockDelegate,所以这个方法不能被调用

如何调用方法的实际实现?

2月10日更新:

我用:

 OCMStub([mockDelegate adLoaded:OCMOCK_ANY error:OCMOCK_ANY])
      .andDo(^BOOL(id<adDelegate> localSelf, NSArray *array, NSError *error) {
        *error = [NSError errorWithDomain:@"Error" code:0 userInfo:nil];
        return NO;
      });

出现错误:

Incompatible block pointer types passing 'BOOL (^)(__strong id<adDelegate>, NSArray *__strong, NSError *__strong)' to parameter of type 'void (^__strong)(NSInvocation *__strong)'

请教如何解决?

几个小时后更新

我找到了答案,所以可以实现:

[OCMExpect([adDelegate adLoaded:OCMOCK_ANY error:OCMOCK_ANY]) andDo:^(NSInvocation *invocation) {
        __unsafe_unretained NSArray *objects = nil;
        [invocation getArgument:&objects atIndex:2];
        
        __unsafe_unretained NSError *error = nil;
        [invocation getArgument:&error atIndex:3];
        
        [self adLoaded:objects error:error];
    }];

这样实现可以获取委托回调触发时传入的参数,然后在单元测试中传递参数class,手动调用委托回调

我会使用 OCMExpect().andDo()。请注意,在当前状态下将 andDo 与 OCMock 一起使用在正确进行内存管理方面有点棘手。有关详细信息,请参阅 https://github.com/erikdoe/ocmock/pull/470

可能是这样的:

OCMExpect([mockDelegate adLoaded:OCMOCK_ANY error:OCMOCK_ANY])
.andDo(^(NSInvocation *invocation) {
        __unsafe_unretained NSArray *array = nil;
        __unsafe_unretained NSError *error = nil;
        [invocation getArgument:&array atIndex:2];
        [invocation getArgument:&error atIndex:3];
        [self adLoaded:array error:error];
      });

或者如果你在 pull 470 中打补丁:

OCMExpect([mockDelegate adLoaded:OCMOCK_ANY error:OCMOCK_ANY])
.andDo(^void(id<adDelegate> localSelf, NSArray *array, NSError *error) {
  [self adLoaded:array error:error];
});