Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning CGRect from mocked method crashes

Tags:

ios

iphone

ocmock

I was just practising OCMock, The problem I am facing here is

I have one method named foo which returns CGRect, this method is called from another method callFoo.

-(CGRect)foo {
    return CGRectMake(10, 10, 10, 10);
}
-(void)callFoo {
    CGRect rect = [self foo];
    NSLog(@"%@",NSStringFromCGRect(rect));
}

My unit test for callFoo method is bellow.

- (void)test__callFoo__invokesWithMockingFoo
{
     ViewController *sut = [[ViewController alloc] init];
     id master = [OCMockObject partialMockForObject:sut];

     CGRect rect = CGRectMake(0, 0, 0, 0);
     [[[master expect] andReturnValue:OCMOCK_VALUE(rect)] foo];
     [sut callFoo];
     [master verify];
 }

When this test case runs,I am getting an unexpected crash when it reaches CGRect rect = [self foo];
I wanted to know why this crash is happening if we return CGRect from mocked method and how to resolve this crash.

Could any one please help to resolve this problem.

Thanks in advance.

P.S : This works fine if I replace CGRect with NSValue. As shown below

 -(NSValue *)foo {
      return [NSValue valueWithCGRect:CGRectMake(10, 10, 10, 10)];
  }
  -(void)callFoo {
      CGRect rect = [[self foo] CGRectValue];
      NSLog(@"%@",NSStringFromCGRect(rect));
  }

and in my test case,

 NSValue *rect = [NSValue valueWithCGRect:CGRectMake(0, 0, 0, 0)];
 [[[master expect] andReturn:rect] foo];

update :
This looks like problem with the memory [but I am not sure, just a guess].

Mocked method will give me correct structure if I create a structure with 2 CGFloat variable, whereas it will crash if I create the structure with 2 double variable or 3 CGFloat variable.

Interesting :)

like image 1000
Prasad Devadiga Avatar asked May 15 '13 07:05

Prasad Devadiga


1 Answers

OCMOCK_VALUE is usually for primitives (BOOL, NSInteger, etc.) It seems that OCMOCK_VALUE doesn't work well with structs, according to the following links.

  • OCMock Return a struct
  • Using a struct with OCMock or Hamcrest
  • OCMock testing the address of a struct

If you use the categories provided by the post OCMock Return a struct, you can do something like:

- (void)test__callFoo__invokesWithMockingFoo {
     ViewController *sut = [[ViewController alloc] init];
     id master = [OCMockObject partialMockForObject:sut];

     CGRect rect = CGRectMake(0, 0, 0, 0);
     [[[master expect] andReturnStruct:&rect objCType:@encode(CGRect)] foo];
     [sut callFoo];
     [master verify];
 }

Alternatively, you can use OCMOCK_STRUCT from Using a struct with OCMock or Hamcrest

- (void)test__callFoo__invokesWithMockingFoo {
     ViewController *sut = [[ViewController alloc] init];
     id master = [OCMockObject partialMockForObject:sut];

     CGRect rect = CGRectMake(0, 0, 0, 0);
     [[[master expect] andReturn:OCMOCK_STRUCT(CGRect, rect)] foo];
     [sut callFoo];
     [master verify];
 }
like image 88
catcyborg Avatar answered Nov 15 '22 20:11

catcyborg