objective c - Mocking KVO with OCMock -


i test key-value-observation working class of mine. has 1 property, depends on another. set so:

+ (nsset *)keypathsforvaluesaffectingsecondproperty {     return [nsset setwithobjects:             @"firstproperty",             nil]; }  - (nsarray *)secondproperty {     return [self.firstproperty array]; } 

i want run unit test verify when firstproperty changes, object bound secondproperty gets notification. @ first thought able use +[ocmockobject observermock], looks can used nsnotificationcenter. best way test this?

i worked on while after @chrispix's answer inspired me work in different direction. started this:

id objecttoobserve = [[theclassbeingtested alloc] init];  id secondpropertyobserver = [ocmockobject mockforclass:[nsobject class]]; [[secondpropertyobserver expect] observevalueforkeypath:@"secondproperty"                                                ofobject:objecttoobserve                                                  change:ocmock_any                                                 context:[ocmarg anypointer]]; [objecttoobserve addobserver:secondpropertyobserver                   forkeypath:@"secondproperty"                      options:nskeyvalueobservingoptionnew                      context:null];  // modify objecttoobserve's firstproperty      [secondpropertyobserver verify]; 

when ran test code, got following message:

ocmockobject[nsobject]: unexpected method invoked: iskindofclass:<??>      expected:     observevalueforkeypath:@"firstproperty" ofobject: 

i did investigation , found -iskindofclass: call mock object didn't expect being passed nskeyvalueobservance class object.

i tried adding following code mock response, values of yes , no both fail exc_bad_access exceptions nskeyvaluewillchange in stack.

bool returnval = no; [[[secondpropertyobserver stub] andreturnvalue:ocmock_value(returnval)] iskindofclass:[ocmarg any]]; 

i stepped more , found code wasn't causing exception - while autoreleasepool being drained. dawned on me needed remove observer. below complete solution, including removing observer.

id objecttoobserve = [[theclassbeingtested alloc] init];  id secondpropertyobserver = [ocmockobject mockforclass:[nsobject class]];  bool returnval = no; [[[secondpropertyobserver stub] andreturnvalue:ocmock_value(returnval)] iskindofclass:[ocmarg any]];  [[secondpropertyobserver expect] observevalueforkeypath:@"secondproperty"                                                ofobject:objecttoobserve                                                  change:ocmock_any                                                 context:[ocmarg anypointer]];  [objecttoobserve addobserver:secondpropertyobserver                   forkeypath:@"secondproperty"                      options:nskeyvalueobservingoptionnew                      context:null];  // modify objecttoobserve's firstproperty      [secondpropertyobserver verify];  [objecttoobserve removeobserver:secondpropertyobserver                      forkeypath:@"secondproperty"]; 

Comments

Popular posts from this blog

jasper reports - Fixed header in Excel using JasperReports -

media player - Android: mediaplayer went away with unhandled events -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -