code like this:
@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
So, is there any way I can get a mocked object RACObserved like normal object?
This is because OCMockito (and OCMock as well) breaks Key-Value Observing, that is, you won't get any KVO "callbacks" from the mocked objects. And RACObserve
uses KVO under the hood.
There are many possible workarounds:
How do you stub a property so that KVO works? Use stubProperty(instance, property, value). For example:
stubProperty(mockEmployee, firstName, @"fake-firstname");
I haven't used OCMockito so I can't tell whether this will really work with RAC.
Use a real object instead of a mock. It will work for some cases (when the object is really simple and you just need to change a property). Of course it shouldn't be used when it will break isolation of the unit test (for example, by sending a network request or accessing a database / file system).
Extract the signal returned by RACObserve
to a property and stub. Instead of
NSArray *signals = @[[RACObserve(MyOtherClassObject, prop) subscribeNext:^{{}]];
do:
NSArray *signals = MyOtherClassObject.prop
where MyOtherClassObject.prop
will return RACObserve(self, prop)
.
Then you can easily stub MyOtherClassObject.prop
and return any signal,
for example [RACSignal return:]
for getting a single value synchronously.