为什么OCMock partialMock打破了KVO?

时间:2013-07-03 19:43:30

标签: objective-c key-value-observing ocmock

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

1 个答案:

答案 0 :(得分: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]];