Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCMock - partial mocking [UIAlertView alloc]

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?

like image 233
larromba Avatar asked Feb 28 '26 09:02

larromba


1 Answers

Here's a more recent example, OCMock now supports class mocks.

id mockAlertView = [OCMockObject mockForClass:[UIAlertView class]];
[[[mockAlertView stub] andReturn:mockAlertView] alloc];
(void)[[[mockAlertView expect] andReturn:mockAlertView]
    initWithTitle:@"Title"
          message:@"Message"
         delegate:OCMOCK_ANY
cancelButtonTitle:OCMOCK_ANY
otherButtonTitles:OCMOCK_ANY, nil];
[[mockAlertView expect] show];

// code that will display the alert here

[mockAlertView verify];
[mockAlertView stopMocking];

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.

like image 127
dB. Avatar answered Mar 01 '26 21:03

dB.