4

如果我有一个对象使用 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
4

1 回答 1

5

KVO 和 OCMock 都在做一些运行时小技巧,通过它们创建实际类的私有子类来执行它们的魔法。KVO 正在做一个叫做“isa-swizzling”的事情,而 OCMock 正在创建一个对象作为原始对象的转发目标

每个系统都在自己的小世界中,有自己的类,与其他系统无关。使用 OCMock 模拟 KVO看起来与您的问题相似。我认为你应该能够通过告诉你的模拟来完成这项工作

[[myMock expect] observeValueForKeyPath:@"foo"
                               ofObject:myObserver
                                 change:[OCMArg any]
                                context:[OCMArg any]];
于 2013-07-03T20:04:51.747 回答