Alex Egli Alex Egli - 25 days ago 9
iOS Question

How do I expose private properties in an iOS unit test?

I am trying to test a method of a class that uses some of the class' private properties. I looked around for best practices on how to access them in a unit test and decided on adding a category for the class in my test implementation file. It still won't let me access them though, I get "unrecgonized selector sent to instance" errors.

My implementation class properties definition (at the top of the ImplementationClass.m file):

@interface ImplementationClass () {
TWPLoadUnitEnum loadUnit;
BOOL recosMatchTargets;
}


The category at the top of my test class:

//interface to expose private variables of test case class
@interface ImplementationClass (Test)
@property(readwrite,assign) TWPLoadUnitEnum loadUnit;
@property(readwrite,assign) BOOL recosMatchTargets;
@end


Where I access the properties:

ImplementationClass *realRecosModal = [[ImplementationClass alloc]
initWithNibName:@"ImplementationClassVC" bundle:nil];
[realRecosModal setLoadUnit:TWPLoadUnitKg]


I get the error on the line where I call "setLoadUnit". Am I not exposing the private property correctly?

Answer
@interface ImplementationClass () {
    TWPLoadUnitEnum loadUnit;
    BOOL recosMatchTargets;
}

Are not properties, they are iVars. If you want them to be properties, you need to have

@interface ImplementationClass ()
@property (nonatomic) TWPLoadUnitEnum loadUnit;
@property (nonatomic) BOOL recosMatchTargets;

If you want to keep the iVar, then in your unit test put

@interface ImplementationClass () {
@public
    TWPLoadUnitEnum loadUnit;
    BOOL recosMatchTargets;
}
@end
  • Note: this uses () instead of (Test). It looks odd but it will work.
  • Important Note: You must provide all iVars and they must be in the exact order or you may cause unexpected behaviors (like random crashes).
Comments