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
Post a Comment