The Pragmatic Ball boy

iOSを中心にやってる万年球拾いの老害エンジニアメモ

Objective-Cでprivateなインスタンス変数やメソッドを外部から変更したり参照する方法

UnitTestなどでテスト対象のクラスのprivateな変数(属性)を参照したり変更したりしたい場合があります。
テストのためにアクセッサを追加したりするのはちょっとあれなので何かいい方法がないか調べてみたらObjective-Cだとテストフレームワークの力を借りるまでもなくあっさりできますね・・

Objective-CのKey Value Codingを利用します。

これはざっくり言うとアクセッサーを用意しなくても、
 setValue: forKeyとvalueForKeyを使えば、名前(Key)でクラスの変数にアクセスできるという代物です。

テスト対象はこのPersonというクラス。

@interface Person()
@property (nonatomic, copy) NSString* name;
@end
 
@implementation Person
- (NSString*)say {
    return name;
}
@end
 
テストコードはこのようになります。
- (void)testName {
    Person * person = [[Person alloc] init];
    
    [person setValue:@"Taro" forKey:@"name"];
    
    XCTAssertEqual(@"Taro", [person valueForKey:@"name"]);
}

 

もう一つの方法としては、テストコード側でテスト対象のカテゴリを書いてやる方法です。

@interface Person(TestPrivate)

@property (nonatomic, copy) NSString* name;

- (NSString*)say

@end

 

- (void)testName {
    Person * person = [[Person alloc] init];
    
    person.name = @"Taro";
    
    XCTAssertEqual(@"Taro", [person say]);
}