2014-04-17 1 views
0

나는 X이라는 클래스와 turtle이라는 메소드를 가지고 있는데, 단위 테스트를 위해 OCMock과 모방하고 싶습니다. 클래스 T.모의 객체를 설정하여 카테고리에 정의 된 실제 구현으로 넘어 가게하려면 어떻게해야합니까?

//X.h 

@interface X 
-(void) turtle; 
@end 

클래스 T는 카테고리를 포함 X와 통신하는 것을 사용한다. 범주 메서드는 turtle을 호출합니다. 단위 테스트에서

//X+utils.h: 

@interface X(Utils) 
-(void) catMethod; 
@end 

//X+utils.m: 
@implementation X(Utils) 
-(void) catMethod 
{ 
    [self turtle]; 
} 
@end 

//T.m 
#import "X+utils.h" 

@implementation T 
-(void) useX:(X*) xInstance 
{ 
    [xInstance catMethod]; 
} 

, 그것은 turtle에 대한 호출을 기대하고 내가 설정 모의하도록.

-(void) test 
{ 
    id mockX = [OCMockObject mockForClass:[X class]] 
    [[mockX expect] turtle]; 

    [instanceOfT useX:mockX]; 

    [mockX verify]; 
} 

는 내가 구현 그것을 사용하기 좋아하는 카테고리를 선택할 수있는 자유를주고 싶습니다 때문에, 카테고리의 메소드의 호출을 기대하지 않는 설정을 모의을한다.

OCMock에서 "예기치 않은"호출이 catMethod으로 걸리므로 호출 useX가 실패합니다.

실제로 범주 구현을 사용하고 실제 인터페이스 X에 정의 된 모의 호출 만 사용하도록 OCMock을 구성 할 수 있습니까?

+1

OCMock은 귀하의 기대를 확인하기 위해 귀하의 목소리에 대한 확인을 요구합니다 - 귀하의 질문을 편집하셨습니다. – e1985

답변

1

여기서 중요한 것은 테스트하려는 것입니다.

테스트 방법에서는 useX:을 테스트하고 있습니다. 순수한 단위 테스트 방법을 사용하면 x에서 catMethod을 호출한다는 것을 테스트해야합니다.

거북이가 마침내 테스트되도록하려면 다음 코드와 같이 부분 모의를 사용할 수 있습니다. 그러나이 방법을 염두에 두어 TuseX:을 테스트 할뿐만 아니라 해당 카테고리에 catMethod을 선언하십시오. -mockForClass를 사용

-(void) test 
{ 
    X *x = [[X alloc] init]; 
    id partialX = [OCMockObject partialMockForObject:x] 
    [[partialX expect] turtle]; 

    [instanceOfT useX:x]; 

    [partialX verify]; 
} 
+0

나는 동의하지 않는다. "T"에 대한 입력은 "X"의 인스턴스이므로 단위 테스트는 임의의 범주가 아닌 "X"로 정의 된 호출 만 예상하면 편리합니다. 구현이 자유롭게 선택할 수있는 특정 범주에 따라 단위 테스트가 취약합니다. 또한 X의 하위 클래스에 대한 동일한 단위 테스트를 더 어렵고 깨지기 쉽도록 재사용합니다. 또한 카테고리의 코드를 복사하여 X의 구현에 붙여 넣을 수 있으며 OCMock에 문제가 없습니다. – JE42

+0

카테고리의 아이디어가 좋거나 나쁜 아키텍처 인 경우 입력하지 않았습니다. 내 대답은 당신이 질문에 노출 코드를 테스트하는 방법을 보여줍니다. – e1985

0

: 당신은 스텁 또는 기대하는 것보다 그것을 다른 전송 된 방법에 예외가 발생합니다 개체를 반환합니다. 지정된 클래스의 구현은 실제로는 없습니다. 단지 인스턴스로 가장합니다. -niceMockForClass : 예기치 않은 메소드에 대해서는 레이즈가 발생하지 않고, 아무 것도하지 않습니다. 이것은 기본적으로 모든 메소드에 대해 빈 구현을 가진 클래스와 같습니다.

다른 대답에서 언급했듯이 실제로 원하는 클래스의 실제 인스턴스를 사용하는 부분 모의입니다. 모든 메소드 호출은 사용자가 스텁, 예상 또는 거부하는 것을 제외하고는 일반 구현을 호출합니다 (심지어 원래 구현을 호출하기 위해 -andForwardToRealObject를 사용할 수 있습니다).

관련 문제