4

我正在尝试对我们的收据验证服务器进行单元测试,虽然我可以更改内部 API 来避免这个问题,但这意味着我们没有完全测试客户端 API,所以我想避免这种情况。

作为我们 API 的一部分,我们通过 SKPaymentTransaction 然后将 Transaction.transactionReceipt 传递到我们的服务器。

为了正确测试这一点,我想创建一个带有我选择的 transactionReceipt 的 SKPaymentTransaction 实例(有效值和无效值)。

不幸的是,SKPaymentTransaction 将 transactionReceipt 属性定义为只读,因此我无法声明将其定义为读写的扩展/子

我似乎也无法将 SKPaymentTransaction 指针转换为 char* 以手动将值注入内存,因为 Xcode 在 ARC 下不允许这样做。

有谁知道我如何才能实现我正在寻找的东西?

谢谢李

4

2 回答 2

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/

于 2014-07-14T14:32:35.973 回答
0

我继承了 SKPaymentTransaction(例如 MutableSKPaymentTransaction),覆盖了只读参数。已经有一个可变的 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
于 2016-02-09T06:11:28.303 回答