If I have an object that uses KVO to observe a property on some object and then create a partial mock 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
Both KVO and OCMock are doing some little runtime tricks whereby they create a private subclass of your actual class in order to perform their magic. KVO is doing a thing called "isa-swizzling", and OCMock is creating an object to be the forwarding target of your original object.
Each system is sort of off in its own little world, with its own class that has nothing to do with the other. Mocking KVO with OCMock looks similar to your problem. I think you should be able to make this work just by telling your mock to