2013-03-24 7 views
11

ユニットテストをしようとすると、正しいUIBarButtonSystemItemがナビゲーションバーボタンに設定されます。UIBarButtonSystemItemをUIBarButtonItemから戻します。

私がバックスタイルを得ることができますが、スタイルは

とは異なる列挙型であるため、buttons.Thisが失敗したために設定されたUIBarButtonSystemItem

列挙型を取得する方法を見つけるように見えることはできませんUIBarButtonSystemItem:

- (void)test_init_should_set_left_right_barButtonItems { 

    UIBarButtonItem *left = mainVCSUT.navigationItem.leftBarButtonItem; 
    UIBarButtonItem *right = mainVCSUT.navigationItem.rightBarButtonItem; 
    [Assert isNotNil:left]; 
    [Assert isNotNil:right]; 

    UIBarButtonItemStyle leftStyle = left.style; 
    UIBarButtonItemStyle rightStyle = right.style; 

    [Assert that:[The int:leftStyle] is:[Equal to:[The int:UIBarButtonSystemItemRefresh]]]; 
    [Assert that:[The int:rightStyle] is:[Equal to:[The int:UIBarButtonSystemItemSearch]]]; 
} 
+0

どのようなアサーションフレームワークを使用しますか? –

答えて

16

のiOS 6.1で(私は他のバージョンをテストしていない)UIBarButtonItemが初期化に渡された値を返す宣言されていない方法systemItemを、持っている、少なくとも。あなたは簡単にキー値コーディングでそれにアクセスすることができます。

UIBarButtonSystemItem systemItemIn = UIBarButtonSystemItemAdd; 
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItemIn target:nil action:NULL]; 
NSNumber *value = [item valueForKey:@"systemItem"]; 
UIBarButtonSystemItem systemItemOut = [value integerValue]; 
NSLog(@"systemItemIn = %d, systemItemOut = %d", systemItemIn, systemItemOut); 

問題が解決しない場合、あなたはこの情報を格納するUIBarButtonItemクラスのインスタンス変数の内部の匿名構造体のtypedef、および使用を作成することができますプライベートIVARの名前、とObjective Cの実行時、以下に示すよう:

//Copied from UIBarButtonItem.h, this is the struct used for the _barButtomItemFlags ivar 
typedef struct { 
    unsigned int enabled:1; 
    unsigned int style:3; 
    unsigned int isSystemItem:1; 
    unsigned int systemItem:7; 
    unsigned int viewIsCustom:1; 
    unsigned int isMinibarView:1; 
    unsigned int disableAutosizing:1; 
    unsigned int selected:1; 
    unsigned int imageHasEffects:1; 
} FlagsStruct; 

// In our test code 
// Instantiate a bar button item 
UIBarButtonSystemItem systemItemIn = UIBarButtonSystemItemAdd; 
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItemIn target:nil action:NULL]; 

// Set up variables needed for run time functions 
Class barItemClass = [item class]; 
BOOL foundIt = NO; // We check this flag to make sure we found the ivar we were looking for 
ptrdiff_t ivarOffset = 0; // This will be the offset of _barButtomItemFlags within the bar button item object 

// Iterate through all of UIBarButtonItem's instance variables 
unsigned int ivarCount = 0; 
Ivar *ivarList = class_copyIvarList(barItemClass, &ivarCount); 
for (int i = 0; i < ivarCount; i++) { 
    Ivar ivar = ivarList[i]; 
    const char *ivarName = ivar_getName(ivar); 
    if (!strcmp(ivarName, "_barButtonItemFlags")) { 
     // We've found an ivar matching the name. We'll get the offset and break from the loop 
     foundIt = YES; 
     ivarOffset = ivar_getOffset(ivar); 
     break; 
    } 
} 
free(ivarList); 

if (foundIt) { 
    // Do a little pointer math to get the FlagsStruct - this struct contains the system item value. 
    void *itemPointer = (__bridge void *)item; 
    FlagsStruct *flags = itemPointer + ivarOffset; 
    UIBarButtonSystemItem systemItemOut = flags->systemItem; 
    NSLog(@"systemItemIn = %d, systemItemOut = %d", systemItemIn, systemItemOut); 
    BOOL equal = (systemItemIn == systemItemOut); 
    if (equal) { 
     NSLog(@"yes they are equal"); 
    } 
    else { 
     NSLog(@"no they are not"); 
    } 
} 
else { 
    // Perhaps Apple changed the ivar name? 
    NSLog(@"didn't find any such ivar :("); 
} 

あなたがそれに近づくいずれにせよ、それが変わる可能ですので、私は多分あなたのテストが唯一のバージョンで条件付きで実行したことをお勧めしたいですOSはこれらのアプローチのいずれかをサポートすることを確認しました。

関連する問題