Let's say I have a class:
@interface MyClass
@end
@implementation MyClass {
myType *_myIvar;
}
@end
And I'd like to expose it for testing. I see two ways to do this:
@interface MyClass
// Pragma mark - Expose for testing
@property myIvar;
@end
@implementation MyClass
@end
-(void)myTest {
myType *myIvar = [myClass valueForKey:@"_myIvar"];
}
Which method is preferred?
First - you don't test private methods or state of a class for unit-testing, as per TDD best practices.
Having that said, however, sometimes it's the only way to observer possible side-effects. I personally always wrap any ivar of a class with a property. For data which is not supposed to appear in the public interface I put it in the extension inside of the implementation file:
// Implementation file
@interface TDWClass ()
@property (strong, nullable) NSString *tdw_p_message;
@end
P.S. This also helps to maintain certain semantic for the given property (you immediately can see not just storage modifier, but other attributes the property is supposed to follow: like, being read-only, nullability, etc..)
When it comes to testing such a property, this approach helps to conveniently read any "private" property (or accessing a private method) by re-declaring it in a category:
// XCTest file
@interface TDWClass (XCTest)
@property (strong, nullable) NSString *tdw_p_message;
@end