2013-07-03 2 views
4

Если у меня есть объект, который использует KVO для наблюдения за свойством на каком-либо объекте, а затем создает частичный макет для этого наблюдателя, я больше не получаю никаких уведомлений. Почему это?Почему OCMock partialMock прерывает KVO?

Вот минимальный пример:

@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 

ответ

5

Оба КВО и OCMock делают некоторые маленькие во время выполнения трюков в котором они создают частный подкласс вашего фактического класса для того, чтобы выполнять свою магию , KVO делает вещь под названием "isa-swizzling", а OCMock создает объект, который будет forwarding target вашего исходного объекта.

Каждая система отличается от своего маленького мира своим собственным классом, который не имеет ничего общего с другим. Mocking KVO with OCMock похож на вашу проблему. Я думаю, вы должны сделать эту работу, просто сообщив своему макету

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

хороший ответ, но это действительно воняет для меня прямо сейчас! – RyanM

Смежные вопросы