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