4

我需要能够确定是否调用了类方法。我怎样才能用 OCMock 做到这一点?

4

4 回答 4

6

从 OCMock 版本 2.1 开始,此功能开箱即用。您现在可以像存根实例方法一样存根类方法。

于 2013-03-16T20:23:33.197 回答
3

一种方法是将类方法包装在您自己的类的方法中。因此,假设您的班级必须致电[SomeOtherClass classMethod:someString]. invokeClassMethod:你可以像这样在你的类上创建一个方法:

-(NSString *)invokeClassMethod:(NSString *)someString {
    return [SomeOtherClass classMethod:someString];
}

然后在您的测试中,您创建一个部分模拟并期望invokeClassMethod:

-(void)testSomething {
    id partialMock = [OCMockObject partialMockForObject:actual];
    [[[partialMock expect] andReturn:@"foo"] invokeClassMethod:@"bar"];

    [actual doSomething:@"bar"];

    [partialMock verify];
}

如果要验证invokeClassMethod 调用,可以抛出异常:

-(void)testSomethingElse {
    id partialMock = [OCMockObject partialMockForObject:actual];
    [[[partialMock stub] andThrow:[NSException exceptionWithName:@"foo" reason:@"Should not have called invokeClassMethod:" userInfo:nil] invokeClassMethod:OCMOCK_ANY];

    [actual doSomething:@"bar"];
}

invokeClassMethod如果调用excpetion 将导致测试失败。

于 2011-04-11T03:44:50.380 回答
2

正如 zneak 在他们对您的问题的评论中提到的那样,看看这个答案

从那里的评论中,查看这个基于块的类方法混合实现。

OCMock似乎不直接支持您想要做的事情,但是这个解决方案非常好!

于 2012-07-02T04:18:22.290 回答
1

或者,假设你有这个类:

@interface ABCCleverClass : NSObject
+ (id)specialMethod;
@end

你想模拟这个类方法。一种选择是在此类上创建一个类别,该类别定义和实现测试支持。然后,您可以将被测类中的类方法的实现与该类别中的模拟类交换。

#import <objc/runtime.h>

@interface ABCCleverClass (TestSupport)
+ (id)mockSpecialMethod;
@end

@implementation ABCCleverClass (TestSupport)

+ (void)load {
  Method original = class_getClassMethod([ABCCleverClass class], @selector(specialMethod));
  Method mocked = class_getClassMethod([ABCCleverClass class], @selector(mockSpecialMethod));
  method_exchangeImplementations(original, mocked);
}

+ (id)mockSpecialMethod {
  // Perform mock method. You may need to add more class methods
  // in order to configure this.
}

@end
于 2013-10-06T16:41:03.703 回答