2014-07-14 28 views
4

我想單元測試我們的收據驗證服務器,雖然我可以改變內部API以避免這個問題,但這意味着我們沒有完全測試客戶端API,我喜歡避免這種情況。修改NSObject的內部屬性(特別是SKPaymentTransaction)

作爲我們API的一部分,我們通過SKPaymentTransaction並將Transaction.transactionReceipt傳遞給我們的服務器。

爲了正確地測試這個,我想用我選擇的transactionReceipt(有效和無效的值)創建一個SKPaymentTransaction的實例。

不幸的是,SKPaymentTransaction定義transactionReceipt屬性爲只讀,並且我不能聲明一個擴展/子類它定義爲讀寫由於this

我似乎也不能將SKPaymentTransaction指針強制轉換爲char *來手動在內存中注入值,因爲Xcode不允許在ARC下執行此操作。

有沒有人有我如何能夠實現我所期待的想法?

感謝 李

回答

3

原來我能調配的transactionReceipt吸氣劑注入我自己的數據到電話。

所以我最終像

-(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/

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