我正在尝试对我们的收据验证服务器进行单元测试,虽然我可以更改内部API以避免此问题,但这意味着我们没有完全测试客户端API,所以我想避免这种情况。
作为我们API的一部分,我们通过SKPaymentTransaction,然后将Transaction.transactionReceipt传递到我们的服务器。
为了正确测试,我想创建一个SKPaymentTransaction实例,其中包含我选择的transactionReceipt(有效值和无效值)。
不幸的是,SKPaymentTransaction将transactionReceipt属性定义为只读,并且我无法声明由于this而将其定义为readwrite的扩展/子类。
我似乎也无法将SKPaymentTransaction指针强制转换为char *以手动将值注入内存中,因为Xcode不会在ARC下允许这样做。
有没有人知道我如何才能达到我想要的目标?
由于 利
答案 0 :(得分:3)
原来我可以调用transactionReceipt getter将自己的数据注入到调用中。
所以我最终得到像
这样的东西-(void)test_function
{
SKPaymentTransaction* invalidTransaction = [[SKPaymentTransaction alloc] init];
Method swizzledMethod = class_getInstanceMethod([self class], @selector(replaced_getTransactionReceipt));
Method originalMethod = class_getInstanceMethod([invalidTransaction class], @selector(transactionReceipt));
method_exchangeImplementations(originalMethod, swizzledMethod);
// Call to receipt verification server
}
- (NSData*)replaced_getTransactionReceipt
{
return [@"blah" dataUsingEncoding:NSUTF8StringEncoding];
}
我写了一篇博文,展示了我的流程,并在此提供了更多详细信息 http://engineering-game-dev.com/2014/07/23/injecting-data-into-obj-c-readonly-properties/
答案 1 :(得分:0)
我将SKPaymentTransaction(例如MutableSKPaymentTransaction)子类化,覆盖readonly参数。已经存在可以使用的可变SKPaymentTransaction,或者您可以以类似的方式覆盖SKPayment。
示例:
在头文件(MutableSKPaymentTransaction.h)文件中
#import <StoreKit/StoreKit.h>
@interface MutableSKPaymentTransaction : SKPaymentTransaction
@property (readwrite, copy, nonatomic) NSError * error;
@property (readwrite, copy, nonatomic) SKPayment * payment;
@property (readwrite, copy, nonatomic) NSString * transactionIdentifier;
@property (readwrite, copy, nonatomic) NSDate * transactionDate;
@property (readwrite, copy, nonatomic) NSArray * downloads;
@property (readwrite, copy, nonatomic) SKPaymentTransaction *originalTransaction;
@property (assign, nonatomic) SKPaymentTransactionState transactionState;
@end
并在方法文件(MutableSKPaymentTransaction.m)中:
#import "MutableSKPaymentTransaction.h"
@implementation MutableSKPaymentTransaction
// readonly override
@synthesize error = _error;
@synthesize payment = _payment;
@synthesize transactionIdentifier = _transactionIdentifier;
@synthesize transactionDate = _transactionDate;
@synthesize downloads = _downloads;
@synthesize originalTransaction = _originalTransaction;
@synthesize transactionState = _transactionState;
@end