2

我一直在尝试模拟一个简单的属性UITextField

@property(nonatomic,readonly,getter=isEditing) BOOL editing;

我试图模拟这两种方式

1.)使用完整的类方法混合技术(通常对于基于类的方法,我会这样做)

- (void)swapOutTextFieldIsEditing
{
    method_exchangeImplementations(
            class_getClassMethod([UITextField class], @selector(isEditing)),
            class_getClassMethod([self class], @selector(isEditingEnabledMock))
    );
}

- (void)resetTextFieldIsEditing
{
    method_exchangeImplementations(
            class_getClassMethod([self class], @selector(isEditingEnabledMock)),
            class_getClassMethod([UITextField class], @selector(isEditing))
    );
}

+ (BOOL)isEditingEnabledMock {
    return isEditingMockResult;
}

2.) 使用自定义 ocmock 助手创建自定义“并返回布尔”方法

 - (id)andReturnBool:(BOOL)aValue {
     NSValue *wrappedValue = nil;
     wrappedValue = [NSValue valueWithBytes:&aValue
                                   objCType:@encode(BOOL)];

     return [self andReturnValue:wrappedValue]; 
}

遗憾的是,这两种技术都失败了,我几乎可以肯定这是因为这是UITextField标记为只读 w/getter 的正常属性(以前在 iOS 上从未见过)

**失败以下NSLog总是返回 (null) - 意思是我不能存根

- (IBAction)next
{
    for (int i = 0; i<[self.fieldsArray count]; i++) {
        NSLog(@"is this field being edited? %@", [[self.fieldsArray objectAtIndex:i] isEditing]);
    }
}

这是我的基本存根语法(与上述一起使用)

id firstField = [OCMockObject niceMockForClass:[UITextField class]];
[[[firstField stub] andReturnBool:YES] isEditing];

有谁知道另一种方法来存根这个结果?如果不是上面列出的两种方法呢?我在这里做错了什么?

先感谢您

4

2 回答 2

1

您似乎将类方法与实例方法混淆了。运行时函数class_getClassMethod返回一个类方法,但由于您感兴趣的方法是属性访问器,它不能是类方法(类没有属性,只有实例有)。相反,用于class_getInstanceMethod获取访问器方法。

于 2012-06-11T00:22:26.907 回答
1

当您使用此存根设置时

id firstField = [OCMockObject niceMockForClass:[UITextField class]];
[[[firstField stub] andReturnBool:YES] isEditing];

你还在用firstField做什么?您确定其他对象与firstField(模拟实例)交互,还是它们与在 XIB 文件中实例化的 UITextField 的真实实例交互?

对于无法注入模拟并且必须处理在其他地方创建的实例的情况,OCMock 提供了部分模拟。这些允许您在现有对象上存根方法。在您的情况下,您可以执行以下操作:

id firstField = ... // somehow get a reference to the actual field object
id firstFieldMock = [OCMockObject partialMockForObject:firstField];
[[[firstFieldMock stub] andReturnBool:YES] isEditing];

之后,当另一个对象在 firstField 上调用isEditing模拟将拦截它。

于 2012-06-11T15:46:02.307 回答