2011-12-08 7 views
4

次のコードの単体テストを書く必要があります。私はクラスメソッドcanMakePaymentsを模倣したい、返すはい、いいえ、canMakePaymentsがクラスメソッド(+)になるまでに良いメソッドが見つからない場合、すべてのOCMockメソッドがすべてであるようですメソッド( - )に使用されます。クラスメソッド(+)をモックする方法は?

ご意見やご感想をお寄せいただきありがとうございます。ありがとう。

// SKPaymentQueue.h 
// StoreKit 
if ([SKPaymentQueue canMakePayments]){ 
    .... 
} 
else{ 
    ... 
} 
+4

ポイントと笑う:

-(BOOL)canMakePayments { return [SKPaymentQueue canMakePayments]; } 

は、その後、あなたはその方法を模擬しますか? (申し訳ありませんが、抵抗できませんでした) – Abizern

答えて

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 

だから、これはFakePaymentQueueSKPaymentQueueを置き換え、参照してください。テストはTestingSubclassに対して実行できるようになりました。

+1

テスト中のクラスとは何ですか?つまり、SKPaymentQueue、またはSKPaymentQueueを呼び出す別のクラスに対してテストを書いていますか? –

+0

Hey Reid;あなたの親切な返事に感謝します。 テストクラスに別のpaymentQueueClassを実装する必要があるのでしょうか?またはオリジナルのフレームワークメソッドカテゴリ(UnitTests)をハックしますか? 私はあなたの解決策を完全に理解していないようですが、私は多くのヒントをくれますか、ありがとうございます。 – jianhua

+0

私のテストクラスは、SKPaymentQueueを呼び出す別のクラスですか? – jianhua

12

一つのアプローチは、独自のインスタンスメソッドでクラスメソッドをラップすることです。それを

-(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]; 
} 
+0

ああ!とても簡単です! –

+0

返信いただきありがとうございます。コードは単体テストを行う方が簡単です。 – jianhua

+0

とても助かりました、ありがとう! – Rahul

関連する問題