Why does OCMock partialMock interrupt KVO?

If I have an object that uses KVO to observe a property on an object and then creates a partial layout for that observer, I no longer receive any notifications. Why is this?

Here's a minimal example:

@interface TestPartialMockAndKVO : SenTestCase @end @implementation TestPartialMockAndKVO - (void)test { // Should print "Changed!" when foo property is changed MyObserver* myObserver = [[[MyObserver alloc] init] autorelease]; // But with this line, there is no print out [OCMockObject partialMockForObject:myObserver]; [myObserver setFoo:@"change"]; } @end 

-

 @interface MyObserver : NSObject @property (copy) NSString* foo; @end @implementation MyObserver - (id)init { self = [super init]; [self addObserver:self forKeyPath:@"foo" options:0 context:NULL]; return self; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"Changed!"); } - (void)dealloc { ... } @end 
+4
source share
1 answer

Both KVO and OCMock do small tricks at runtime, so they create a private subclass of your actual class to do their magic. KVO does a thing called "isa-swizzling," and OCMock creates an object to redirect the source object.

Each system is partly in its small world, with its own class, which has nothing to do with the other. Mocking KVO with OCMock is similar to your problem. I think you should do this work by simply telling the layout

 [[myMock expect] observeValueForKeyPath:@"foo" ofObject:myObserver change:[OCMArg any] context:[OCMArg any]]; 
+5
source

Source: https://habr.com/ru/post/1489575/


All Articles