我需要能够确定是否调用了类方法。 我怎么能用OCMock做到这一点?
答案 0 :(得分:6)
从OCMock版本2.1开始,这支持开箱即用。您现在可以使用与存根实例方法相同的方式存根类方法。
答案 1 :(得分:3)
一种方法是将class方法包装在您自己的类中的方法中。因此,假设您的班级必须致电[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
,则激活将导致测试失败。
答案 2 :(得分:2)
正如zneak在对您的问题的评论中提到的那样,请查看this answer,
从那里的评论中,结帐this block-based implementation类方法调整。
OCMock
似乎没有直接支持您想要做的事情,但这个解决方案非常好!
答案 3 :(得分: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