Exposing for unit testing in objective c

38 views Asked by At

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:

  1. expose the ivar as a property:
@interface MyClass
  // Pragma mark - Expose for testing
  @property myIvar; 
@end
    
@implementation MyClass
@end
  1. Use key value coding:
-(void)myTest {
  myType *myIvar = [myClass valueForKey:@"_myIvar"];
}

Which method is preferred?

1

There are 1 answers

0
The Dreams Wind On BEST ANSWER

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