I'm having an issue with the OCMock
framework for iOS. I'm essentially trying to mock UIAlertView
's initWithTitle:message:delegate
... method. The example below doesn't work in the sense that the stubbed return value isn't returned when I call the initWithTitle
method.
UIAlertView *emptyAlert = [UIAlertView new];
id mockAlert = [OCMockObject partialMockForObject:[UIAlertView alloc]];
[[[mockAlert stub] andReturn:emptyAlert] initWithTitle:OCMOCK_ANY message:OCMOCK_ANY delegate:nil cancelButtonTitle:OCMOCK_ANY otherButtonTitles:nil];
UIAlertView *testAlertReturnValue = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil];
if(testAlertReturnValue == emptyAlert) {
NSLog(@"UIAlertView test worked");
}
However, it does work if I use the same idea for NSDictionary
.
NSDictionary *emptyDictionary = [NSDictionary new];
id mockDictionary = [OCMockObject partialMockForObject:[NSDictionary alloc]];
[[[mockDictionary stub] andReturn:emptyDictionary] initWithContentsOfFile:OCMOCK_ANY];
NSDictionary *testDictionaryReturnValue = [[NSDictionary alloc] initWithContentsOfFile:@"test"];
if(testDictionaryReturnValue == emptyDictionary) {
NSLog(@"NSDictionary test worked");
}
One thing I notice is that the method "forwardInvocationForRealObject:
" in "OCPartialMockObject.m
" is called during the NSDictionary
initWithContentsOfFile
call, but not during the UIAlertView
initWithTitle call.
Could this be an OCMock
bug?
I had issues with mocking
UIAlertView
as well, and my best guess is that it's the vararg that's throwing it off (can't 100% remember though). My solution was to create a factory method forUIAlertView
and add it as a category.Notice that I replace the varargs with an
NSArray
. This method is definitely mockable, and the syntax is pretty similar now that we have array literals:If you have the flexibility to change your source code, this'd be my suggestion.
EDIT
Looking more closely at your code, you are creating a partial mock, stubbing it's init method, then not doing anything with it. It's possible the way you are doing it might actually work if you replace the
[UIAlertView alloc]
with the mock you create. Can't say for sure because I do remember having issues with it.For some reason mocking +(id)alloc in UIAlertView doesn't seem to work, so rather than partially mock UIAlertView and stub the (for example) initWithTitle: method, I now use the following fix. Hopefully this will be useful to anyone else facing similar problems.
XCTest_UIAlertView+MyCustomCategory.m
UIAlertView+MyCustomCategory.m
Here's a more recent example, OCMock now supports class mocks.
It's pretty common to have the alert being triggered from a callback on something. One way to wait for that is using a verifyWithDelay, see https://github.com/erikdoe/ocmock/pull/59.