2016-09-20 7 views
3

내 코드는 C 라이브러리 함수 호출 :사용이

@implementation Store 
    ... 
    -(void) doWork { 
    // this is a C function from a library 
    int data = getData(); 
    ... 
    } 
end 

내가, 내가 내 테스트의 C 함수 getData()을 조롱하려는 위의 기능을 시험 단위 걸, 여기 내 테스트입니다 경우 : Use of undeclared identifier 'mData' 내부 조롱 getData() 기능 :

@interface StoreTests : XCTestCase { 
    int mData; 
    Store *store; 
} 
@end 

@implementation StoreTests 

-(void) setUp { 
    [super setUp]; 
    mData = 0; 
    store = [[Store alloc] init]; 
} 

-(void) testDoWork { 
    // this call will use the mocked getData(), no problem here. 
    [store doWork]; 
} 

// mocked getData() 
int getData() { 
    mData = 10; // Use of undeclared identifier 'mData', why? 
    return mData; 
} 

... 
@end 

이 왜 컴파일러 오류가?

int mData; 
@interface StoreTests : XCTestCase { 
    Store *store; 
} 
@end 
... 
+0

'- (INT) GetData의() {', 나는 기능 body'를 기대'이상한 컴파일러 오류가 발생, 내 현재 코드 - (INT) GetData의은() {' – ozgur

+0

는 아니, 난에'를 변경하는 경우 조롱 된 함수는 프로덕션 코드에 의해 호출됩니다. mocked 함수 내에서 mData에 값을 할당 할 때만 문제가 발생합니다. 다시 C 함수입니다. –

+1

나는 당신이 의미하는 것을 이해하고, 시도하고, 나는 위의 코멘트를 썼다. –

답변

1

인스턴스 메소드와 변수가 어떻게 작동하는지 당신은 오해하고 있습니다 :

내 질문에 대한 하나의 해결책을 발견
+0

매우 비 의도적이다. 감사! –

0

, 즉, @interface StoreTests : XCTestCase 위 같은 것을 mData를 선언합니다.

모든 경우에있어서, ->는 예 self->mData을, mData 등의 현재 인스턴스를 참조하는 변수 self (또는 "현재 대상")과 인스턴스 변수의 사용을 가지고 self를 사용하여 그 변수를 액세스하기위한 속기 필드 액세스를위한 (Objective-) C 연산자. 자체에서 온

-(void) setUp { 
    [super setUp]; 
    self->mData = 0; 
    self->store = [[Store alloc] init]; 
} 

그러나 어디 인스턴스에 대한 참조를 self 수행합니다 그래서 setup 방법이 쓰여진 "긴 손 '인가? 음, 그것은 숨겨진 추가 인수로 인스턴스 메소드에 자동으로 전달되는 마법적이고 이상한 것은 아닙니다. 이것을 보여주기 위해 의사 코드로 전환합니다.

-(void) setUp withSelf:(StoreTest *)self { 
    [super setUp]; 
    self->mData = 0; 
    self->store = [[Store alloc] init]; 
} 

과 같은 호출 :로 효과적으로를 컴파일 귀하의 setup 방법입니다

[myStoreTests setup withSelf:myStoreTests]; 

가 자동으로 추가 self을 추가 :

StoreTests *myStoreTests = ... 

[myStoreTests setup]; 

효과적으로 같은으로 컴파일 논의.

지금 위의 모든 단지 방법에 적용하고, 인스턴스 변수와 메소드에 액세스하도록 할 수 있습니다, 그것은 일반 C 함수에 적용되지 않습니다 - 그들은 숨겨진 self 인수가 없으며 인스턴스 변수에 액세스 할 수 없습니다.

당신이 인터페이스의 mData 외부 선언의 추가 질문에 대해 답 언급 솔루션 :

int mData; 
@interface StoreTests : XCTestCase { 
    Store *store; 
} 
@end 

가 대신 인스턴스 변수 인의하는 전역 변수mData을 변경합니다. C 함수는 전역 변수에 액세스 할 수 있습니다. 그러나 이는 클래스의 모든 인스턴스가 동일한 mData을 공유한다는 것을 의미합니다.이 경우 모든 인스턴스에 대해 하나가 아닌 mData 만 있습니다.

인스턴스 변수를 전역 변수로 만드는 것은 이와 같은 문제에 대한 일반적인 해결책이 아니지만이 경우에는 StoreTests 클래스의 인스턴스가 둘 이상 존재하지 않을 가능성이 있으므로이 경우에는 적절한 솔루션입니다. 당신의 mData가 고유해야합니다, 그래서 당신은 단지, 프로그램에 주어진 이름을 가진 하나 개의 글로벌 변수를 가질 수 있고 StoreTests의,뿐만 아니라 코드는 프로그램 내에서 어떤 코드에서 액세스 :

당신은 단 하나의 변화를 확인해야합니다 . 당신은 나의 static로 변수를 선언이를 완화 할 수

static int mData; 

이 글로벌로 변수를 유지하지만 아마 StoreTests 단지 코드 선언, 같은 파일 내 코드는 볼 수 있습니다.

HTH는