2014-01-24 5 views
4

CBPeripheralManager 클래스에 CBPeripheralManagerDelegate의 역할을하는 클래스를 단위 테스트하고 싶습니다. 일반적으로 외부 클래스 종속성을 스텁 아웃하려면 클래스 이니셜 라이저를 통해 전달하거나 속성을 통해 종속성 주입 양식을 사용합니다. 싱글 톤 기반의 API를 다룰 때 키위와 같은 라이브러리를 사용하여 싱글 톤 (즉, [ClassName stub:@selector(sharedInstance) andReturn:myStubbedInstance])을 반환하는 클래스 수준 메소드를 스텁링 할 수있었습니다. CBPeripheralManager을 조롱하는 경우의 문제는 이니셜 라이저가 대리인 인스턴스를 사용한다는 것입니다. 그래서 내 클래스를 사용하는 코드는 다음과 같은 것을 할 필요가있을 것이다 :코어 블루투스 API와 상호 작용하는 하나의 단위 테스트 코드는 어떻게됩니까?

PeripheralManagerWrapper *wrapper = [[PeripheralManagerWrapper alloc] init]; 
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:wrapper queue:nil options:nil]; 
wrapper.peripheralManager = peripheralManager; 

그런 다음 내 PeripheralManagerWrapper 클래스를 테스트 단위, 단순히 인스턴스화 수와 조롱 CBPeripheralManager 전달합니다. 그러나, 나는이 래퍼 객체의 호출 코드가이 설정을 거치도록 요구하는 것을 좋아하지 않는다. 이 상황을 다루기위한 더 좋은 패턴이 있습니까? 키위와 OCMockito를 모두 사용했지만, allocinit 메서드를 CBPeripheralManager으로 스터핑 한 다음이 인스턴스를 PeripheralManagerWrapper 의 이니셜 라이저로 인스턴스화하는 것만으로는 부족합니다.

답변

4

IMHO, 핵심 블루투스 API는 단위 테스트에 완벽하게 매치됩니다. 모든 대리자 콜백은 관리자와 관련 매개 변수를 사용하므로 내부 상태 대신 이러한 인수를 사용하는 패턴을 따르는 경우 원하는 모든 것을 전달할 수 있습니다. 이렇게하려면 모의 객체를 사용하는 것이 가장 좋은 방법입니다. 단원 테스트 중에는 관리자의 행동을 조롱하지 말아야합니다. 코드와 API의 상호 작용을 확인하는 데 주력해야합니다.

래퍼는 통합 테스트에 더 적합 할 수 있습니다. 하지만 사실, 코어 블루투스 코드의 통합 테스트는 내 경험에 맞게 직접 수행하는 것이 좋습니다. 스택은 안정적인 테스트를 할 수있을만큼 안정적이지 못하며 테스트 코드는 스택 오류에 대해 강화되어야합니다. 이는 분명히 API를 살펴보면 문서화되거나 예측할 수 없으므로 실제로 어렵습니다. 반면에 테스트 코드는 스택의 잘못된 동작을 시뮬레이션해야합니다. 테스트 코드가 가능할 때도 있지만 테스트 코드보다 복잡하지 않은 경우에도 테스트 코드가 복잡 할 수 있습니다.

+0

예, 래퍼는 테스트에 관한 것이 아니라 ViewController에서 블루투스 동작을 격리시키는 것입니다. 래퍼가 가장 좋은 접미사가 아닐 수도 있습니다. –

+0

좋습니다. 제 3 자 API와 비즈니스 로직을 분리하는 것은 항상 좋은 습관입니다. 내가 너의 질문에 대답 했니? – allprog

+0

예. 미표로 표시하지 않으셔서 죄송합니다. –