你们有任何建议或讨论将不胜感激。谢谢。
// SKPaymentQueue.h
// StoreKit
if ([SKPaymentQueue canMakePayments]){
....
}
else{
...
}
答案 0 :(得分:13)
一种方法是将class方法包装在您自己的实例方法中:
-(BOOL)canMakePayments {
return [SKPaymentQueue canMakePayments];
}
然后你嘲笑那个方法:
-(void)testCanHandlePaymentsDisabled {
Foo *foo = [[Foo alloc] init];
id mockFoo = [OCMockObject partialMockForObject:foo];
BOOL paymentsEnabled = NO;
[[[mockFoo stub] andReturnValue:OCMOCK_VALUE(paymentsEnabled)] canMakePayments];
// set up expectations for payments disabled case
...
[foo attemptPurchase];
}
答案 1 :(得分:4)
由于您无法通过提供不同的实例来拦截该方法,因此您可以为类方法执行的操作是提供不同的类。像这样:
+ (Class)paymentQueueClass
{
return [SKPaymentQueue class];
}
然后,呼叫点变为:
Class paymentQueueClass = [[self class] paymentQueueClass];
if ([paymentQueueClass canMakePayments])
...
这引入了“测试接缝”或控制点,允许我们指定除SKPaymentQueue
以外的类。现在让我们做一个替代:
static BOOL fakeCanMakePayments;
@interface FakePaymentQueue : SKPaymentQueue
@end
@implementation FakePaymentQueue
+ (void)setFakeCanMakePayments:(BOOL)fakeValue
{
fakeCanMakePayments = fakeValue;
}
+ (BOOL)canMakePayments
{
return fakeCanMakePayments;
}
@end
严格来说,这不是一个“模拟对象” - 它是一个“虚假对象”。不同之处在于模拟对象验证了它的调用方式。假对象只提供存根结果。
现在让我们创建一个我们想要测试的原始类的测试子类。
@interface TestingSubclass : OriginalClass
@end
@implementation TestingSubclass
+ (Class)paymentQueueClass
{
return [FakePaymentQueue class];
}
@end
您看,这会将SKPaymentQueue
替换为FakePaymentQueue
。您的测试现在可以针对TestingSubclass
运行。