2013-07-03 3 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

KVO 및 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