2013-05-15 12 views
14

我只是在練習OCMock,我這裏面臨的問題是從模擬的方法返回的CGRect崩潰

我有一個方法叫foo返回CGRect,這種方法是從另一種方法callFoo調用。

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

我的單元測試爲callFoo方法如下。

- (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]; 
} 

當此測試用例運行,當它達到CGRect rect = [self foo];
我想知道爲什麼這種碰撞發生的事情,如果我們從mocked method和如何返回CGRect解決這一崩潰,我得到了意想不到的崩潰。

任何人都可以幫助解決這個問題。

在此先感謝。

P.S:這工作正常,如果我用NSValue替換CGRect。 As shown below

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

,並在我的測試情況下,

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

更新:
這看起來像內存的問題[但我不知道,只是猜測。

模擬的方法會給我正確的結構,如果我創建了一個結構2 CGFloat變量,而如果我創建2 double變量或3 CGFloat可變結構就會崩潰。

有趣:)

+3

這似乎是OCMock中的一個錯誤。它最終使foo指向部分模擬中的空實現(您​​可能已經看到,如果直接調用foo,則可以通過測試)。一個(當然不是很好)的解決方法是將foo放在不同的類中並模擬它。 –

+0

我不確定它是否是OCMock中的錯誤,但是當我嘗試使用與CGRect ie類似的自定義結構時。 struct包含兩個結構體(struct1&struct2),它包含兩個變量。但結果是一樣的,它墜毀了。但如果我的結構,即結構1和結構2只包含一個變量,那麼測試將通過 –

+1

這是一個OCMock中的錯誤,現在已經修復:https://github.com/erikdoe/ocmock/pull/41如果你看看關於pull請求的評論,你會發現爲什麼只有一些(通常是很大的)結構有問題。 –

回答

0

這似乎是一個bugOCMock。現在已經修復了。

4

OCMOCK_VALUE通常是原語(BOOL,NSInteger的,等等)似乎OCMOCK_VALUE不與結構很好地工作,根據下面的鏈接。

如果您使用後OCMock Return a struct提供的類別,你可以這樣做:

- (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]; 
} 

或者,你可以使用OCMOCK_STRUCT fr OM 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]; 
} 
+0

我試過'CGRect rect = {0,0,0,0}; NSValue * valRect = [NSValue valueWithBytes:&rect objCType:@encode(CGRect)]; [[[master expect] andReturnValue:valRect] foo];'但它墜毀了。 –

+0

您是否試過'[[[master expect] andReturn:valRect] foo];'? – catcyborg

+0

是的,我試過也仍然是一樣的結果。 –