1

私はOCUnitとOCMockを初めて使用し、このテスト方法について詳しく知りたいと思います。

スタブを作成するOCUnitとOCMockの機能がモックオブジェクトなどを生成することを知っています...

まだクラックできていない特定のユースケースがあります。

-(bool) isGameCenterAvailable
{
    // Check for presence of GKLocalPlayer API.
    Class gcClass = (NSClassFromString(@"GKLocalPlayer"));

    // The device must be running running iOS 4.1 or later.
    bool isIPAD = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
    NSString *reqSysVer = (isIPAD) ? @"4.2" : @"4.1";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);

return (gcClass && osVersionSupported);
}

これがユニットテストに関する私の問題です:

1)NSClassFromString(@ "GKLocalPlayer")は、foundation.hの呼び出しであり、私が知っているこれをスタブする機能はありません。

2)[[UIDevice currentDevice] systemVersion]は、関数のスコープに対してローカルな呼び出しです。私のメソッドは別のクラス(UIDevice)内のメソッドを呼び出します。関数呼び出しをスタブでオーバーライドして、この関数のすべてのパスを実行するための定型の回答を返します。

テスト対象の関数のスコープ内でクラスがインスタンス化されている場合、クラスをモックできるかどうかはわかりません。

さらに、#1のようなクラスメソッドをどのようにテストしますか。

ここでの唯一の答えはリファクタリングですか?

4

1 に答える 1

1

#1 については、GKLocalPlayerAPIをチェックするメソッドを作成できます。

-(BOOL)isGKLocalPlayerSupported {
    return (NSClassFromString(@"GKLocalPlayer")) != nil;
}

次に、そのメソッドをモックできます。テスト対象のクラス内にメソッドを作成する場合は、部分モックを使用できます。

-(void)testIsGameCenterAvailable {
    // create gameCenterChecker instance to test...

    id mockChecker = [OCMockObject partialMockForObject:gameCenterChecker];
    BOOL supported = YES;
    [[[mockChecker stub] andReturnValue:OCMOCK_VALUE(supported)] isGKLocalPlayerSupported];

    expect([gameCenterChecker isGKLocalPlayerSupported]).toBeTruthy();
}

プロジェクトによっては、それをユーティリティ クラスに入れる方が理にかなっている場合があります。その場合、ユーティリティをモックします。

-(void)testIsGameCenterAvailable {
    id mockUtility = [OCMockObject mockForClass:[MyUtility class]];
    [MyUtility setSharedInstance:mockUtility];
    BOOL supported = YES;
    [[[mockUtility stub] andReturnValue:OCMOCK_VALUE(supported)] isGKLocalPlayerSupported];

    // create gameCenterChecker instance to test...

    expect([gameCenterChecker isGKLocalPlayerSupported]).toBeTruthy();
}

システムのバージョンとデバイスに対して同じアプローチを取ることができます。

-(NSString *)systemVersion;
-(BOOL)isIpad;
于 2012-06-29T15:53:27.860 に答える