You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OCMock Stub类方法并使用doInvocation报错:无匹配实例方法选择器

解决OCMock打桩带回调的类方法编译错误问题

这个报错的核心原因是你用实例Mock对象去打桩类方法了——OCMock里,实例Mock只能处理实例方法,类方法属于类本身,得用专门的类Mock对象来操作,所以编译器才会提示“无匹配选择器的实例方法”。

下面给你具体的修复方案和正确写法:

第一步:创建类Mock对象

对于OCMock 3及以上版本,要创建类Mock而不是实例Mock,用OCMClassMock(或者[OCMockObject mockForClass:...]也可以,两者在类Mock场景下等价):

// 替换成你实际的类名
Class imageLoaderMock = OCMClassMock([YourImageLoadingClass class]);

第二步:正确打桩类方法并执行回调

接下来对类方法进行stub,同时通过andDo取出回调block并执行:

OCMStub([imageLoaderMock loadImageForRelativeFilePath:[OCMArg any] completionBlock:[OCMArg any]])
.andDo(^(NSInvocation *invocation) {
    // 取出completion block参数:注意NSInvocation的参数索引,self是0,_cmd是1,第一个业务参数是2,第二个是3
    void (^completion)(UIImage *, NSError *) = nil;
    [invocation getArgument:&completion atIndex:3];
    
    // 执行回调,你可以根据测试场景返回模拟的图片或错误
    if (completion) {
        // 示例:返回一张测试图片,无错误
        UIImage *mockImage = [UIImage imageWithColor:[UIColor redColor]];
        completion(mockImage, nil);
        
        // 如果要模拟错误场景,改成下面的写法:
        // NSError *mockError = [NSError errorWithDomain:@"TestError" code:-1 userInfo:nil];
        // completion(nil, mockError);
    }
});

关键注意点

  • 别搞混实例Mock和类Mock:如果你要打桩的是+[XXX loadImage...]这种类方法,必须用类Mock对象;如果是-[XXX loadImage...]实例方法,才用实例Mock。
  • NSInvocation的参数索引容易踩坑:一定要数清楚,self(类对象本身)是索引0,_cmd(方法选择器)是索引1,之后的业务参数依次从2开始递增。

内容的提问来源于stack exchange,提问作者Shrikanth Ananth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:55:34