OCMockito:RACObserve 模拟对象总是失败

OCMockito: RACObserve a mocked object always fail

这样的代码:

@implementation MyClass

- (void)func
{
//MyOtherClassObject is an object passed in when initialising MyClass
    NSArray *signals = @[[RACObserve(MyOtherClassObject, prop) subscribeNext:^{{}]];
}

@end

@implementation MyTest

- (void)testSomething
{
    MyOtherClass *mock = mock([MyOtherClass class]);
    MyClass *myObject = [[MyClass alloc] initWithOtherObject:mock]
    [myObject func];  //this won't work since RACObserve will return nil instead of a valid signal
}

@end

那么,有什么方法可以让模拟对象 RACObserved 像普通对象一样?

这是因为 OCMockito(以及 OCMock)破坏了 Key-Value Observing,也就是说,您不会从模拟对象中获得任何 KVO "callbacks"。 RACObserve 在后台使用 KVO。 有许多可能的解决方法:

  1. 如 OCMockito 文档中所述:

How do you stub a property so that KVO works? Use stubProperty(instance, property, value). For example:

stubProperty(mockEmployee, firstName, @"fake-firstname");

我没有使用过 OCMockito,所以我不知道这是否真的适用于 RAC。

  1. 使用 真实 对象而不是模拟对象。它适用于某些情况(当对象非常简单并且您只需要更改 属性 时)。当然,当它会破坏单元测试的隔离时(例如,通过发送网络请求或访问数据库/文件系统),它不应该被使用。

  2. RACObserve 编辑的信号 return 提取到 属性 和存根。而不是

NSArray *signals = @[[RACObserve(MyOtherClassObject, prop) subscribeNext:^{{}]];

做:

NSArray *signals = MyOtherClassObject.prop

其中 MyOtherClassObject.prop 将 return RACObserve(self, prop)。 然后你可以轻松地存根 MyOtherClassObject.prop 和 return 任何信号, 例如 [RACSignal return:] 用于同步获取单个值。